zoukankan      html  css  js  c++  java
  • cdq分治入门--BZOJ3262: 陌上花开

    n<=100000个人,每个人三个属性Ai,Bi,Ci,一个人i的等级为Ai>=Aj,Bi>=Bj,Ci>=Cj的人数,求每个等级有多少人。

    裸的三维偏序。按照常规思路,一维排序,一维归并,一维利用单调性或用树状数组维护,这里选择后者。

    先按Ai排序,然后在分治过程中,solve(l,mid),solve(mid+1,r),然后考虑(l,mid)对(mid+1,r)答案的贡献,先把这两部分分别按B排序,然后两个指针一起扫,扫的过程中,把C的值作下标丢进树状数组,查询时相当于树状数组前缀和。

    思路很好,可样例过不了。

    原因:在计算过程中默认后面对前面是没有贡献的,但按Ai排序后,相同的Ai值可能引起后面对前面的贡献。

    方法:保证后面对前面无贡献,一开始就先按A再按B最后按C排序即可。

    那还有重复的呢?去重呗!

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<algorithm>
     5 //#include<iostream>
     6 using namespace std;
     7 
     8 int n,m;
     9 #define maxn 200011
    10 int ord[maxn],tmpord[maxn];
    11 struct BIT
    12 {
    13     int a[maxn];
    14     BIT() {memset(a,0,sizeof(a));}
    15     void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;}
    16     int query(int x) {int ans=0;for (;x;x-=x&-x) ans+=a[x];return ans;}
    17 }t;
    18 
    19 struct Point
    20 {
    21     int x,y,z,cnt;
    22     bool operator < (const Point &b) const
    23     {return x<b.x || (x==b.x && y<b.y) || (x==b.x && y==b.y && z<b.z);}
    24 }q[maxn],p[maxn];
    25 int ans[maxn],ansnum[maxn];
    26 void solve(int L,int R)
    27 {
    28     if (L==R) {ans[L]+=p[L].cnt-1;ord[L]=L;return;}
    29     const int mid=(L+R)>>1;
    30     solve(L,mid);
    31     solve(mid+1,R);
    32     int i=L,j=mid+1,k=L;
    33     while (i<=mid && j<=R)
    34     {
    35         if (p[ord[i]].y<=p[ord[j]].y)
    36         {
    37             tmpord[k++]=ord[i];
    38             t.add(p[ord[i]].z,p[ord[i]].cnt);
    39             i++;
    40         }
    41         else
    42         {
    43             tmpord[k++]=ord[j];
    44             ans[ord[j]]+=t.query(p[ord[j]].z);
    45             j++;
    46         }
    47     }
    48     for (;j<=R;j++) ans[ord[j]]+=t.query(p[ord[j]].z),tmpord[k++]=ord[j];
    49     for (int ii=L;ii<i;ii++) t.add(p[ord[ii]].z,-p[ord[ii]].cnt);
    50     for (;i<=mid;i++) tmpord[k++]=ord[i];
    51     for (int x=L;x<=R;x++) ord[x]=tmpord[x];
    52 }
    53 
    54 int lisan[maxn];
    55 int main()
    56 {
    57     scanf("%d%d",&n,&m);
    58     for (int i=1;i<=n;i++)
    59     {
    60         scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);
    61         lisan[i]=q[i].z;
    62     }
    63     sort(lisan+1,lisan+1+n);
    64     for (int i=1;i<=n;i++) q[i].z=lower_bound(lisan+1,lisan+1+n,q[i].z)-lisan;
    65     sort(q+1,q+1+n);
    66     int tot=0;q[0].x=-0x3f3f3f3f;
    67     for (int i=1;i<=n;i++)
    68     {
    69         if (q[i-1].x==q[i].x && q[i-1].y==q[i].y && q[i-1].z==q[i].z) p[tot].cnt++;
    70         else p[++tot]=q[i],p[tot].cnt=1;
    71     }
    72     solve(1,tot);
    73     for (int i=1;i<=tot;i++) ansnum[ans[i]]+=p[i].cnt;
    74     for (int i=0;i<n;i++) printf("%d
    ",ansnum[i]);
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    QT自定义控件插件化简要概述
    wildfly9 配置SSL单向认证/https
    wildfly-9.0.2 web项目部署详细步骤
    SQL Server 2008 数据库日志文件丢失处理方法
    win7 64位系统 pl/sql 无法解析指定的连接标识符解决办法
    mybatis 应用参考
    去除浏览器下jquey easyui datagrid、combotree 缓存问题
    java 页面url传值中文乱码的解决方法
    jasperreports-5.6 + jaspersoftstudio-5.6 生成pdf 文件中文无法正常显示问题
    HTML5实现在线抓拍
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7886679.html
Copyright © 2011-2022 走看看