标签:
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