zoukankan      html  css  js  c++  java
  • 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
    ", ans[i] );
    80 }
    View Code
  • 相关阅读:
    回想四叉树LOD地形(上)
    项目优化经验分享(四)需求与原型图
    CF79D Password
    2018-3-7-VisualStudio-csproj-添加-ItemGroup-的-Service-
    2018-3-7-VisualStudio-csproj-添加-ItemGroup-的-Service-
    2018-8-10-如何入门-C++-AMP-教程
    2018-8-10-如何入门-C++-AMP-教程
    2019-11-6-Roslyn-how-to-use-WriteLinesToFile-to-write-the-semicolons-to-file
    2019-11-6-Roslyn-how-to-use-WriteLinesToFile-to-write-the-semicolons-to-file
    2019-1-4-win10-uwp-win2d-CanvasVirtualControl-与-CanvasAnimatedControl
  • 原文地址:https://www.cnblogs.com/idy002/p/4456341.html
Copyright © 2011-2022 走看看