HDU

来源:互联网 发布:opensuse和ubuntu 编辑:程序博客网 时间:2024/06/13 20:56
题意:有二元组(a,b),三元组(c,d,e)。当b == e时它们能构成(a,c,d)。 

然后,当不存在 [ (u,v,w)!=(a,b,c)且u>=a,v>=b,w>=c ]时,则是一个better集合里的元素。 

问这个better集合有几个元素.

思路:首先能确定的是每一个原来的三元组最多构造一个新的三元组,因为当b == e时,我们只能选所有(a, b)当中a最大的那个(选其他的没有意义),然后问题是怎么判断一个新的三元组是不是better集合里的元素,我们可以按照

(a, c, d)的优先级排序,然后逆序逐个将(c,d)插入二维树状数组当中,并且每次插入之前更新答案就好了,将(c,d)看成平面坐标,那么二维树状数组就可以看成用来维护平面上在一个点右下方的点的数量。

代码:

#include<bits/stdc++.h>using namespace std;const int MAXN = 100010;const int N = 1010;int bit[N + 10][N + 10];struct node{int x, y, z, num;node(){}node(int _x, int _y, int _z, int _num) : x(_x), y(_y), z(_z), num(_num) {}bool operator < (node a) const{if(x != a.x) return x < a.x;if(y != a.y) return y < a.y;return z < a.z;}bool operator == (node a) const{return (x == a.x && y == a.y && z == a.z);}}p[MAXN];int w[MAXN], cnt[MAXN];int top;void add(int i, int j, int x){for(int u = i; u <= N; u += u & -u)for(int v = j; v <= N; v += v & -v)bit[u][v] += x;}int sum(int i, int j){int res = 0;for(int u = i; u; u -= u & -u)for(int v = j; v; v -= v & -v)res += bit[u][v];return res;}int query(int x1, int y1, int x2, int y2){return sum(x2, y2) - sum(x1 - 1, y2) - sum(x2, y1 - 1) + sum(x1 - 1, y1 - 1);}int solve(){memset(bit, 0, sizeof(bit));int ans = 0;for(int i = top; i >= 0; i--) //注意是逆序处理{if(query(p[i].y, p[i].z, N, N) == 0) ans += p[i].num;add(p[i].y, p[i].z, 1);}return ans;}int main(){int T, n, m, a, b, c;cin >> T;for(int kase = 1; kase <= T; kase++){memset(w, 0, sizeof(w));memset(cnt, 0, sizeof(cnt));scanf("%d %d", &n, &m);for(int i = 1; i <= n; i++){scanf("%d %d", &a, &b);if(w[b] < a) w[b] = a, cnt[b] = 1;else if(w[b] == a) cnt[b]++;}top = 0;for(int i = 1; i <= m; i++){scanf("%d %d %d", &a, &b, &c);if(w[c]) p[top++] = node(w[c], a, b, cnt[c]);}sort(p, p + top);int tmp = top; top = 0;for(int i = 1; i < tmp; i++){if(p[top] == p[i]) p[top].num += p[i].num;else p[++top] = p[i];}printf("Case #%d: %d\n", kase, solve());} return 0;}