题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5517
题意:有二元组(a,b),三元组(c,d,e)。当b == e时它们能构成(a,c,d)然后,当不存在(u,v,w)!=(a,b,c)且u>=a,v>=b,w>=c时,则是一个better集合里的元素。问这个better集合有几个元素。
题解:当 c、d 相同时对于当前 e 只有 a 最大的时候才有可能是 better 集合里的元素,所以记录相同的 b 中 最大的 a 以及它出现的次数,然后可以生成一个新的三元组。将三元组排序并去重之后,从后往前更新二维树状数组即可统计答案。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define mst(a,b) memset((a),(b),sizeof(a)) 6 #define mp(a,b) make_pair(a,b) 7 #define pi acos(-1) 8 #define pii pair<int,int> 9 #define pb push_back 10 const int INF = 0x3f3f3f3f; 11 const double eps = 1e-6; 12 const int MAXN = 1e5 + 10; 13 const int MAXM = 1e3 + 10; 14 15 int bx[MAXN],cntb[MAXN]; 16 17 struct node { 18 int a,c,d; 19 ll num; 20 bool operator == (const node &x) { 21 if(a == x.a && c == x.c && d == x.d) return true; 22 return false; 23 } 24 }p[MAXN]; 25 26 bool cmp(node x,node y) { 27 if(x.a != y.a) return x.a < y.a; 28 else if(x.c != y.c) return x.c < y.c; 29 else if(x.d != y.d) return x.d < y.d; 30 return x.num < y.num; 31 } 32 33 int lowbit(int x) { 34 return x & (-x); 35 } 36 37 ll bit[MAXM][MAXM]; 38 39 void update(int x,int y,ll val) { 40 for(int i = x; i <= 1000; i+= lowbit(i)) 41 for(int j = y; j <= 1000; j += lowbit(j)) 42 bit[i][j] += val; 43 } 44 45 ll get(int x,int y) { 46 ll ans = 0; 47 for(int i = x; i > 0; i -= lowbit(i)) 48 for(int j = y; j > 0; j -= lowbit(j)) 49 ans += bit[i][j]; 50 return ans; 51 } 52 53 ll query(int x1,int y1,int x2,int y2) { 54 return get(x2,y2) - get(x1 - 1,y2) - get(x2, y1 - 1) + get(x1 - 1, y1 - 1); 55 } 56 57 int main() { 58 #ifdef local 59 freopen("data.txt", "r", stdin); 60 #endif 61 int cas = 1; 62 int t; 63 scanf("%d", &t); 64 while(t--) { 65 mst(bx, 0); 66 mst(cntb, 0); 67 mst(bit, 0); 68 int n,m; 69 scanf("%d%d",&n,&m); 70 for(int i = 1; i <= n; i++) { 71 int a,b; 72 scanf("%d%d",&a,&b); 73 if(a > bx[b]) bx[b] = a, cntb[b] = 1; 74 else if(a == bx[b]) cntb[b]++; 75 } 76 for(int i = 1; i <= m; i++) { 77 int c,d,e; 78 scanf("%d%d%d",&c,&d,&e); 79 p[i] = {bx[e],c,d,cntb[e]}; 80 } 81 sort(p + 1, p + 1 + m, cmp); 82 int tot = 0; 83 for(int i = 1; i <= m; i++) { 84 if(!p[i].num) continue; 85 if(p[i] == p[tot]) p[tot].num += p[i].num; 86 else p[++tot] = p[i]; 87 } 88 ll ans = 0; 89 for(int i = tot; i >= 1; i--) { 90 if(!query(p[i].c,p[i].d,1000,1000)) ans += p[i].num; 91 update(p[i].c,p[i].d,p[i].num); 92 } 93 printf("Case #%d: %lld ",cas++,ans); 94 } 95 return 0; 96 }