bzoj 3262
题意:给你一些三维上的点,对于每个点,统计三个坐标都小于等于该点的点数。
如果点的范围在300以内,可以用三维树状数组搞,但这题坐标范围太大。
考虑将所有点按照x坐标排序,从左到右,相当于在一个二维平面上插入点,并询问某个点左下方的点数,而后者可以按时间分治,在O(nloglog)复杂度内搞定。(其实可以把x轴看成时间轴)
注意相同点的处理。
(感觉对时间分治就是:将左区间和右区间的修改对其后面的询问的贡献处理掉,合并时就只有左区间的修改和右区间的询问,这就达到了以一个log的复杂度将"修改 询问 修改 修改 询问...”的问题变成了“修改 修改 修改 询问 询问”)
1 #include <cstdio> 2 #include <algorithm> 3 #define N 100010 4 #define K 200010 5 using namespace std; 6 7 struct Trid { 8 int x, y, z; 9 int cnt; 10 int xx; 11 Trid(){} 12 Trid( int x, int y, int z ):x(x),y(y),z(z),cnt(0),xx(x){} 13 bool operator==( const Trid & o ) const { 14 return x==o.x && y==o.y && z==o.z; 15 } 16 bool operator<( const Trid &b ) const { 17 if( x!=b.x ) return x<b.x; 18 if( y!=b.y ) return y<b.y; 19 return z<b.z; 20 } 21 }; 22 23 int n, k; 24 Trid trid[N]; 25 int bit[K]; 26 int ans[N]; 27 28 void modify( int pos, int v ) { 29 for( int i=pos; i<=k; i+=i&-i ) 30 bit[i] += v; 31 } 32 int query( int pos ) { 33 int rt=0; 34 for( int i=pos; i; i-=i&-i ) 35 rt += bit[i]; 36 return rt; 37 } 38 bool cmp_yzx( const Trid &a, const Trid &b ) { 39 if( a.y!=b.y ) return a.y<b.y; 40 if( a.z!=b.z ) return a.z<b.z; 41 return a.x<b.x; 42 } 43 void cdq( int lf, int rg ) { 44 if( lf==rg ) return; 45 int mid=(lf+rg)>>1; 46 cdq(lf,mid); 47 cdq(mid+1,rg); 48 sort( trid+lf, trid+rg+1, cmp_yzx ); 49 for( int i=lf; i<=rg; i++ ) { 50 if( trid[i].x<=mid ) 51 modify( trid[i].z, +1 ); 52 if( trid[i].x>mid ) 53 trid[i].cnt += query( trid[i].z ); 54 } 55 for( int i=lf; i<=rg; i++ ) 56 if( trid[i].x<=mid ) 57 modify( trid[i].z, -1 ); 58 } 59 int main() { 60 scanf( "%d%d", &n, &k ); 61 for( int i=1,x,y,z; i<=n; i++ ) { 62 scanf( "%d%d%d", &x, &y, &z ); 63 trid[i] = Trid( x, y, z ); 64 } 65 sort( trid+1, trid+1+n ); 66 for( int i=1,j; i<=n; i++ ) { 67 for( j=i; j<=n && trid[j]==trid[i]; j++ ); 68 for( int k=i; k<j; k++ ) 69 trid[k].cnt += j-k-1; 70 i = j-1; 71 } 72 for( int i=1; i<=n; i++ ) 73 trid[i].x = i; 74 cdq( 1, n ); 75 for( int i=1; i<=n; i++ ) { 76 ans[trid[i].cnt]++; 77 } 78 for( int i=0; i<n; i++ ) 79 printf( "%d\n", ans[i] ); 80 }