题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5517
-------------------------------------------------------------------------------------------------------
前置知识以及思维难度上不算很高 不过实现对于我这种弱渣来说还是太复杂了(很多处理比较绕)
我们稍作分析(xiangyun)后可以发现 有可能最优且本质不同的三元组C只有不超过M个
对于二元组A b相同时只用保留a最大的 并且把相同的A合并掉
处理完之后再将B与之合体 得到不超过M个C
此时先按一个元素排序 再根据另两个元素值 用二维树状数组统计下就好了
-------------------------------------------------------------------------------------------------------
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10, lim = 1001; int t, n, m, len, lenm; struct sa { int x,y,c; }a[N],ua[N]; struct sc { int x,y,z,c; }c[N]; bool f[lim][lim]; bool cmp1(const sa &aa,const sa &bb) { return aa.y < bb.y || (aa.y == bb.y && aa.x > bb.x); } bool cmp2(const sc &aa,const sc &bb) { return aa.x > bb.x || (aa.x == bb.x && aa.y < bb.y) || (aa.x == bb.x && aa.y == bb.y && aa.z < bb.z); } int main() { scanf("%d", &t); for(int ca = 1; ca <= t; ++ca) { scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++i) scanf("%d%d", &a[i].x, &a[i].y); sort(a + 1, a + 1 + n, cmp1); len = lenm = 0; memset(ua, 0, sizeof ua); for(int i = 1; i <=n;) { ++len; ua[len].x = a[i].x; ua[len].y = a[i].y; int j = i; while(a[j + 1].x == a[i].x) ++j; ua[len].c = j - i + 1; while(a[j]. y == a[i].y) ++j; i = j; } int tx,ty,tz; for(int i = 1; i <= m; ++i) { scanf("%d%d%d", &tx, &ty, &tz); int L = 1, R = len, mid; while(L < R) { mid = (L + R) >> 1; if(ua[mid].y >= tz) R = mid; else L = mid + 1; } if(ua[R].y == tz) { ++lenm; c[lenm].x = ua[R].x; c[lenm].y = lim - tx; c[lenm].z = lim - ty; c[lenm].c = ua[R].c; } } n = lenm; sort(c + 1,c + 1 + n,cmp2); memset(f, 0, sizeof f); long long ans = 0; for(int i = 1; i <= n; ++i) { if(c[i].x == c[i + 1].x && c[i].y == c[i + 1].y && c[i].z == c[i + 1].z) { c[i + 1].c += c[i].c; continue; } bool tmp = 0; for(int p = c[i].y; p ; p -= p & -p) for(int q = c[i].z; q; q -= q & -q) tmp |= f[p][q]; if(!tmp) ans += c[i].c; for(int p = c[i].y; p < lim; p += p & -p) for(int q = c[i].z; q < lim; q += q & -q) f[p][q] = 1; } printf("Case #%d: %lld ", ca, ans); } return 0; }