zoukankan      html  css  js  c++  java
  • BZOJ 3262 陌上花开 (三维偏序CDQ+树状数组)

    题目大意:

    题面传送门 

    三维偏序裸题

    首先,把三元组关于$a_{i}$排序

    然后开始$CDQ$分治,回溯后按$b_{i}$排序

    现在要处理左侧对右侧的影响了,显然现在左侧三元组的$a_{i}$都小于等于右侧

    而$c_{i}$这一维需要用权值树状数组维护

    归并排序时,已知左侧右侧两个指针分别是$i,j$

    如果$b_{i} leq bj$,将左侧已经遍历过的三元组的$c_{i}$推入树状数组,然后$i++$

    如果$b_{i}>bj$,那么右侧能取到的贡献就是树状数组内$leq c_{j}$的三元组数量,然后$j++$

    可三元组有重复的啊!

    如果我们不去重,假设有两个相同的三元组,靠前的三元组会得不到后面的贡献

    还需要去重,并额外记录相同三元组数量

    这道题的判定条件三个元是小于等于

    发现我们只关于$a_{i}$排序也不行啊

    在归并过程中会发现有一些$b_{i}$或者是$c_{i}$明明比较大,却得不到后面较小的贡献

    这是由于小于等于的情况也合法,而我们必须让较大的在后面,才能保证后面能取到前面的贡献

    所以排序过程中第二维还要按$b_{i}$排序,第三维按$c_{i}$

     1 #include <vector>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define N1 100100
     6 #define ll long long
     7 #define dd double
     8 #define inf 0x3f3f3f3f3f3f3f3fll
     9 using namespace std;
    10 
    11 int gint()
    12 {
    13     int ret=0,fh=1;char c=getchar();
    14     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
    15     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
    16     return ret*fh;
    17 }
    18 int n,nn,K;
    19 struct node{
    20 int id,num,a,b,c;
    21 friend bool operator == (const node &s1,const node &s2)
    22 {return (s1.a==s2.a)&&(s1.b==s2.b)&&(s1.c==s2.c);}
    23 friend bool operator < (const node &s1,const node &s2)
    24 {
    25     if(s1.a!=s2.a) return s1.a<s2.a;
    26     if(s1.b!=s2.b) return s1.b<s2.b;
    27     return s1.c<s2.c;
    28 }
    29 }p[N1],t[N1],tmp[N1];
    30 
    31 struct b_{i}T{
    32 int s[N1<<1];
    33 void update(int x,int w){for(int i=x;i<=K;i+=(i&(-i))) s[i]+=w;}
    34 int query(int x){int ans=0; for(int i=x;i>0;i-=(i&(-i))) ans+=s[i]; return ans;}
    35 }b;
    36 int f[N1],hs[N1],que[N1],tl;
    37 void CDQ(int L,int R)
    38 {
    39     if(R-L<=1) return;
    40     int M=(L+R)>>1;
    41     CDQ(L,M); CDQ(M,R);
    42     int i=L,j=M,cnt=0;
    43     while(i<M&&j<R)
    44     {
    45         if(t[i].b<=t[j].b){
    46             b.update(t[i].c,t[i].num); 
    47             tmp[++cnt]=t[i]; i++; que[++tl]=cnt;
    48         }else{
    49             f[t[j].id]+=b.query(t[j].c);
    50             tmp[++cnt]=t[j]; j++;
    51         }
    52     }
    53     while(i<M){tmp[++cnt]=t[i]; i++;}
    54     while(j<R){f[t[j].id]+=b.query(t[j].c); tmp[++cnt]=t[j]; j++;}
    55     while(tl) i=que[tl--],b.update(tmp[i].c,-tmp[i].num);
    56     for(i=L;i<R;i++) t[i]=tmp[i-L+1];
    57 }
    58 
    59 int main()
    60 {
    61     scanf("%d%d",&n,&K);
    62     int i;
    63     for(i=1;i<=n;i++) p[i].a=gint(),p[i].b=gint(),p[i].c=gint();
    64     sort(p+1,p+n+1); 
    65     for(i=1;i<=n;i++) 
    66         if(!(p[i]==p[i-1])) t[++nn]=p[i],t[nn].num=1;
    67         else t[nn].num++;
    68     for(i=1;i<=nn;i++) t[i].id=i;
    69     CDQ(1,nn+1);
    70     for(i=1;i<=nn;i++) hs[f[t[i].id]+t[i].num-1]+=t[i].num;
    71     for(i=0;i<n;i++) printf("%d
    ",hs[i]);
    72     return 0;
    73 }
  • 相关阅读:
    Apache ab压力测试时出现大量的错误原因分析
    图解linux下的top命令
    [转载]几种切词工具的使用(转)
    大规模中文文本处理中的自动切词和标注技术
    [转载]盘点:94版《三国演义》演员的今昔对比照
    搜索引擎切词详解
    iphone-命令行编译之--xcodebuild
    Appium IOS 自动化测试初探
    手把手教你appium_mac上环境搭建
    Appium-doctor 检测Xcode未安装问题
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10203117.html
Copyright © 2011-2022 走看看