码迷,mamicode.com
首页 > 其他好文 > 详细

2014上海区域赛 I题 Defeat the Enemy 离线读入 在线更新 线段树套优先队列

时间:2015-05-26 10:40:06      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5158

UVALive 7146

 

题意

自己有n个军队 敌方有m个军队

每个军队都有攻击力和防守力两种属性

当一方的攻击力>=对方的防御力时 可以把对方杀掉

在一次战斗中有可能出现双方都死了或者双方都没死的情况

另外要求己方不能有两只不同军队跟对方的同一只军队交战

问是否能全歼敌军

如果可以的话,输出最多可以存活多少只己方军队

 

我们队的做法稍微有点复杂,我尽量解释得清楚一点:

(待补)

 

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>

using namespace std;

typedef long long ll;

const int maxn = 100000;

struct Node{
    int A,D,ID;
};

priority_queue<int, vector<int>, greater<int> > que[maxn+10];

struct tree{
    int l, r, data;
}T[maxn*4];

void buildTree(int now ,int l, int r)
{
    int lson = now<<1, rson = lson|1;
    T[now].l = l; T[now].r = r;T[now].data = 0;

    if(l == r)
        return;
    int mid = (l+r)>>1;
    buildTree(lson, l, mid);
    buildTree(rson, mid+1, r);
}

void change(int now, int aim)
{
    int lson = now<<1, rson = lson|1;
    if(T[now].l == aim && T[now].r == aim)
    {
        T[now].data ^= 1;
        return;
    }
    int mid = T[lson].r;
    if(aim <= mid)
        change(lson, aim);
    else
        change(rson, aim);
    T[now].data = T[lson].data+T[rson].data;
}

int getSum(int now, int index)
{
    int lson = now<<1, rson = lson|1;
    if(T[now].r == index)
        return T[now].data;
    int mid = T[lson].r;
    if(index <= mid)
        return getSum(lson, index);
    else
        return T[lson].data+getSum(rson, index);
}

int findPos(int now, int aim)
{
    int lson = now<<1, rson = lson|1;
    if(T[now].data < aim)
        return 0;
    if(T[now].l == T[now].r)
        return T[now].l;
    if(T[lson].data < aim)
        return findPos(rson, aim-T[lson].data);
    else
        return findPos(lson, aim);
}

bool cmpD(Node a, Node b)
{
    return a.D<b.D;
}
bool cmpA(Node a, Node b)
{
    return a.A<b.A;
}

Node a[maxn+10],b[maxn+10];

void init(int cnt)
{
    buildTree(1, 1, cnt);
    for(int i = 1; i <= cnt; i++)
        while(!que[i].empty()) que[i].pop();
}
int main()
{
    //freopen("in2.txt", "r", stdin);

    int T;
    scanf("%d", &T);
    int kase = 0;
    while(T--)
    {
        int n,m;
        printf("Case #%d: ", ++kase);
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; i++)
            scanf("%d%d", &a[i].A, &a[i].D);
        for(int i = 0; i < m; i++)
            scanf("%d%d", &b[i].A, &b[i].D);
        if(m > n)
        {
            printf("-1\n");
            continue;
        }

        sort(a,a+n,cmpD);
        sort(b,b+m,cmpA);

        int cnt = 2, cnta = 0;
        int ans = 0;
        for(int i = 0; i < m; i++)
        {
            b[i].ID = cnt;
            while(i < m-1 && b[i+1].A == b[i].A)  b[++i].ID = cnt;
            while(cnta < n && a[cnta].D <= b[i].A)
                a[cnta++].ID = cnt-1;
            //if(cnta == n && i != m) {ans = -1;break;}
            cnt++;
        }

        for(int i = cnta; i < n; i++)
            a[i].ID = cnt-1;

        sort(a, a+n, cmpA);
        sort(b, b+m, cmpD);
        for(int i = n-1; m-n+i >= 0; i--)
            if(a[i].A < b[m-n+i].D)
            {
                ans = -1;
                break;
            }

        if(ans == -1)
        {
            printf("-1\n");
            continue;
        }
        init(cnt);
        cnta = n-1;
        for(int i = m-1; i >= 0; i--)
        {
            while(a[cnta].A >= b[i].D && cnta >= 0)
            {
                if(que[a[cnta].ID].empty())
                {
                    change(1, a[cnta].ID);
                }
                que[a[cnta].ID].push(a[cnta].D);
                cnta--;
            }
            int id = b[i].ID;
            int sum = getSum(1, id-1);
            int index = findPos(1, sum+1);
            if(index == 0)
            {
                ans++;
                int tmp = 1;
                int ind = findPos(1,1);
                que[ind].pop();
                if(que[ind].empty())
                    change(1, ind);
            }
            else
            {
                que[index].pop();
                if(que[index].empty())
                    change(1, index);
            }
        }
        printf("%d\n", n-ans);
    }

    return 0;
}

 

2014上海区域赛 I题 Defeat the Enemy 离线读入 在线更新 线段树套优先队列

标签:

原文地址:http://www.cnblogs.com/dishu/p/4529783.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!