「BZOJ」「3262」陌上花开
CDQ分治
WA :在solve时,对y、z排序以后,没有处理「y、z相同」的情况,也就是说可能(1,2,3)这个点被放到了(2,2,3)的后面,也就是统计答案在前,插入该点在后……也就没有统计到!
sad
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 const int N = 200010; 9 int n,k; 10 struct node{ 11 int x,y,z,id; 12 }a[100010], b[100010]; 13 bool operator != (node a,node b){ 14 return a.x != b.x || a.y != b.y || a.z != b.z; 15 } 16 bool operator < (node a,node b){ 17 return a.x < b.x || (a.x == b.x && a.y < b.y) || (a.x == b.x && a.y == b.y && a.z < b.z); 18 } 19 bool cmp(node a,node b){ 20 return a.y < b.y || (a.y == b.y && a.z < b.z) || (a.y == b.y && a.z == b.z && a.id < b.id); 21 } 22 int ans[N], rank[N], num[N]; 23 24 int val[N], vis[N], times; 25 inline int lowbit(int x){ 26 return x & (-x); 27 } 28 void add(int pos, int v){ 29 for(int i = pos; i <= k; i += lowbit(i)) 30 if (vis[i] == times) val[i] += v; 31 else val[i] = v, vis[i] = times; 32 } 33 int query(int pos){ 34 int ans = 0; 35 for(int i = pos; i; i -= lowbit(i)) 36 if (vis[i] == times) 37 ans += val[i]; 38 return ans; 39 } 40 41 void solve(int l,int r){ 42 int mid = l + r >> 1; 43 if (l < mid) solve(l, mid); 44 sort(a + l, a + r + 1, cmp); 45 times ++; 46 for(int i = l; i <= r; i ++) 47 if (a[i].id <= mid) add(a[i].z, num[a[i].id]); 48 else rank[a[i].id] += query(a[i].z); 49 sort(a + l, a + r + 1); 50 if (mid + 1 < r) solve(mid + 1, r); 51 } 52 int main(){ 53 freopen("3262.in", "r", stdin); 54 freopen("3262.out", "w", stdout); 55 scanf("%d%d",&n,&k); 56 for(int i = 1; i <= n; i ++) 57 scanf("%d%d%d",&a[i].x, &a[i].y, &a[i].z); 58 sort(a + 1, a + n + 1); 59 for(int i = 1; i <= n; i ++) b[i] = a[i]; 60 int cnt = 0; 61 for(int i = 1; i <= n; i ++) 62 if (b[i] != b[i - 1]) a[++ cnt] = b[i], num[cnt] = 1; 63 else num[cnt] ++; 64 for(int i = 1; i <= cnt; i ++) a[i].id = i, rank[i] = num[i] - 1; 65 // for(int i = 1; i <= cnt; i ++) printf("%d %d %d num = %d\n",a[i].x, a[i].y, a[i].z, num[i]); 66 solve(1, cnt); 67 // for(int i = 1; i <= cnt; i ++) printf("rank[%d] = %d\n",i,rank[i]); 68 for(int i = 1; i <= cnt; i ++) 69 ans[rank[i]] += num[i]; 70 for(int i = 0; i < n; i ++) printf("%d\n",ans[i]); 71 return 0; 72 }