zoukankan      html  css  js  c++  java
  • BZOJ 3295 [CQOI2011]动态逆序对 (三维偏序CDQ+树状数组)

    题目大意:

    题面传送门

    还是一道三维偏序题

    每次操作都可以看成这样一个三元组 $<x,w,t>$ ,操作的位置,权值,修改时间

    一开始的序列看成n次插入操作

    我们先求出不删除时的逆序对总数量,再统计每次删除元素时,减少的逆序对数量

    然后就是三维偏序裸题了吧,第一维时间,第二维操作位置,第三维权值,用树状数组维护即可

    由于逆序对可以在被删除元素的前面或者后面,所以在归并时需要正反遍历各统计一次

     1 #include <vector>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define N1 150100
     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,m,nn,K;
    19 
    20 struct node{
    21 int p,t,x,w,ans;
    22 }a[N1],tmp[N1];
    23 
    24 struct BIT{
    25 int s[N1];
    26 void update(int x,int w){for(int i=x;i<=n;i+=(i&(-i))) s[i]+=w;}
    27 int query(int x){int ans=0; for(int i=x;i;i-=(i&(-i))) ans+=s[i]; return ans;}
    28 }b;
    29 
    30 int que[N1],tl;
    31 void CDQ(int L,int R)
    32 {
    33     if(R-L<=1) return;
    34     int M=(L+R)>>1;
    35     CDQ(L,M); CDQ(M,R);
    36     int i,j,x,cnt;
    37     
    38     i=M-1,j=R-1,cnt=0;
    39     while(i>=L&&j>=M)
    40     {
    41         if(a[i].x>a[j].x){
    42             b.update(a[i].w,a[i].p);
    43             que[++tl]=i; i--; 
    44         }else{
    45             if(a[j].p==-1) a[j].ans+=b.query(a[j].w-1);
    46             j--; 
    47         }
    48     }
    49     while(i>=L) {i--;}
    50     while(j>=M) {if(a[j].p==-1) a[j].ans+=b.query(a[j].w-1); j--;}
    51     while(tl) {x=que[tl--]; b.update(a[x].w,-a[x].p);}
    52     
    53     i=L,j=M,cnt=0;
    54     while(i<M&&j<R)
    55     {
    56         if(a[i].x<a[j].x){
    57             b.update(a[i].w,a[i].p);
    58             que[++tl]=i; tmp[++cnt]=a[i]; i++; 
    59         }else{
    60             if(a[j].p==-1) a[j].ans+=b.query(n)-b.query(a[j].w);
    61             tmp[++cnt]=a[j]; j++;
    62         }
    63     }
    64     while(i<M) {tmp[++cnt]=a[i]; i++;}
    65     while(j<R) {if(a[j].p==-1) a[j].ans+=b.query(n)-b.query(a[j].w); tmp[++cnt]=a[j]; j++;}
    66     while(tl) {x=que[tl--]; b.update(a[x].w,-a[x].p);}
    67     
    68     for(i=L;i<R;i++) a[i]=tmp[i-L+1];
    69 }
    70 int cmp(node s1,node s2){
    71     if(s1.p!=s2.p) return s1.p>s2.p;
    72     return s1.t<s2.t;}
    73 int pos[N1];
    74 
    75 int main()
    76 {
    77     scanf("%d%d",&n,&m);
    78     int i; ll ans=0; nn=n+m;
    79     for(i=1;i<=n;i++) a[i].w=gint(),a[i].x=i,a[i].p=1,a[i].t=i,pos[a[i].w]=i;
    80     for(i=n;i>=1;i--) ans+=b.query(a[i].w),b.update(a[i].w,1);
    81     memset(b.s,0,sizeof(b.s));
    82     for(i=n+1;i<=n+m;i++) a[i].w=gint(),a[i].x=pos[a[i].w],a[i].p=-1,a[i].t=i;
    83     CDQ(1,n+m+1);
    84     sort(a+1,a+n+m+1,cmp);
    85     for(i=n+1;i<=n+m;i++)
    86     {
    87         printf("%lld
    ",ans);
    88         ans-=a[i].ans;
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    使用Kmeans进行聚类,用calinski_harabaz_score评价聚类效果
    使用Autoencoder进行降维
    MongoDB 之 MongoDB简介与安装 MongoDB 1
    我的淘宝客之路 起步
    Excel批量导入Orale
    CAB压缩包文件制作
    策略模式
    设计OA系统的用户角色权限分配
    java语言中的限定词
    jQuery LigerUI使用培训
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10203176.html
Copyright © 2011-2022 走看看