zoukankan      html  css  js  c++  java
  • bzoj 3263 陌上花开(cdq分治,BIT)

     

     

    【题意】

      求满足Ai<=Aj,Bi<=Bj,Ci<=Cj的数对的数目。

       

    【思路】

        cdq分治

        借网上一句话:第一维排序,第二维cdq分治,第三维树状数组维护。

        首先合并三维都是相同的项。

        先按照第一维排序然后cdq分治。

        定义solve(l,r)为解决区间l,r内所有询问且solve结束后区间有序,设mid=(l+r)/2,

      1)  Solve(l,mid)

      2)  Solve(mid+1,r)

      //因为经过第一维排序,所以左区间的a都小于等于右区间的a。

      3)  处理跨立影响。因为已经排过序,所以左区间的a都要小于右区间的a,因为solve后区间有序,所以左右区间都各自按照b排好了序。按照归并排序的思路,计算左区间对每一个右区间内点的贡献:处理到右区间的l2时,将所有左区间内比他的b小的加入BIT,这时候只要查询一次就可以得出左区间对l2的贡献。

      4)  清理BIT,并按照b c大小将左右区间合并使区间有序

      最后根据题目要求转化一下。

      总的时间为O(nlog^2n),bingo

    【代码】

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 const int N = 3*1e5+10;
     8 
     9 struct Node {
    10     int a,b,c,s,ans;
    11 }que[N],a[N];
    12 
    13 bool cmp1(const Node& x,const Node& y) {
    14     return x.b<y.b||(x.b==y.b&&x.c<y.c);
    15 }
    16 bool cmp2(const Node& x,const Node& y) {
    17     if(x.a==y.a&&x.b==y.b) return x.c<y.c;
    18     else if(x.a==y.a) return x.b<y.b;
    19     else return x.a<y.a;
    20 }
    21 
    22 int n,K,C[N],ans[N];
    23 
    24 void add(int x,int v)
    25 {
    26     for(;x<=K;x+=x&-x) C[x]+=v;
    27 }
    28 int query(int x)
    29 {
    30     int res=0;
    31     for(;x;x-=x&-x) res+=C[x];
    32     return res;
    33 }
    34 Node t[N];
    35 void solve(int l,int r)
    36 {
    37     if(l==r) return ;
    38     int mid=(l+r)>>1;
    39     solve(l,mid) , solve(mid+1,r);
    40     int l1=l,l2=mid+1;
    41     while(l2<=r) {
    42         while(l1<=mid && que[l1].b<=que[l2].b) {
    43             add(que[l1].c,que[l1].s);
    44             l1++;
    45         }
    46         que[l2].ans+=query(que[l2].c);
    47         l2++;
    48     }
    49     for(int i=l;i<l1;i++)
    50         add(que[i].c,-que[i].s);
    51     l1=l,l2=mid+1; int pos=l;
    52     while(l1<=mid||l2<=r) {
    53         if(l2>r||(l1<=mid&&cmp1(que[l1],que[l2]))) t[pos++]=que[l1++];
    54         else t[pos++]=que[l2++];
    55     }
    56     for(int i=l;i<=r;i++) que[i]=t[i];
    57 }
    58 void read(int& x)
    59 {
    60     char c=getchar(); x=0;
    61     while(!isdigit(c)) c=getchar();
    62     while(isdigit(c)) x=x*10+c-'0',c=getchar();
    63 }
    64 int main()
    65 {
    66     //freopen("in.in","r",stdin);
    67     //freopen("out.out","w",stdout);
    68     read(n),read(K);
    69     for(int i=1;i<=n;i++)
    70         read(a[i].a),read(a[i].b),read(a[i].c);
    71     sort(a+1,a+n+1,cmp2);
    72     int cnt=0,sz=0;
    73     for(int i=1;i<=n;i++) {
    74         cnt++;
    75         if(a[i].a!=a[i+1].a||a[i].b!=a[i+1].b||a[i].c!=a[i+1].c)
    76         {
    77             que[++sz]=a[i];
    78             que[sz].s=cnt;
    79             cnt=0;
    80         }
    81     }
    82     solve(1,sz);
    83     for(int i=1;i<=sz;i++)
    84         ans[que[i].ans+que[i].s-1]+=que[i].s;
    85     //评级为0~n-1的每级花的数量
    86     for(int i=0;i<n;i++)
    87         printf("%d
    ",ans[i]);
    88     return 0;
    89 }
  • 相关阅读:
    jQuery
    MySQL的引入,绿色包下载和应用
    jsp引用JSTL核心标签库
    Servlet的引入
    Servlet访问Javabean并传结果给jsp
    Spring MVC 中获取session的几种方法
    面试必问系列——hashmap的默认扩容阈值是大于12还是大于等于12
    面试必问系列——重写equals为什么一定要重写hashcode
    分析spring4和spring5日志中的不同
    mysql 查询参数尾部有空格时被忽略
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5254640.html
Copyright © 2011-2022 走看看