zoukankan      html  css  js  c++  java
  • BZOJ 2141 排队 (三维偏序CDQ+树状数组)

    题目大意:略

    洛谷传送门

    [CQOI2015]动态逆序对 这道题一样的思路

    一开始的序列视为$n$次插入操作

    把每次交换操作看成四次操作,删除$x$,删除$y$,加入$x$,加入$y$

    把每次操作都看成一个三元组 $<x,w,t>$ 操作位置,权值,以及操作时间

    变成了一道三维偏序裸题

    外层按操作时间$t$升序,回溯时按操作位置$x$排序

    处理左区间对右区间的影响时,正反两次树状数组求逆序对即可

     1 #include <vector>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define N1 30100
     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,ma,nn,K;
    19  
    20 struct BIT{
    21 int s[N1];
    22 void update(int x,int w){for(int i=x;i<=ma;i+=(i&(-i))) s[i]+=w;}
    23 int query(int x){int ans=0; for(int i=x;i;i-=(i&(-i))) ans+=s[i]; return ans;}
    24 }b;
    25 struct node{int p,x,w,t,ans;}a[N1],tmp[N1];
    26 int c[N1],q[N1],que[N1],tl;
    27  
    28 void CDQ(int L,int R)
    29 {
    30     if(R-L<=1) return;
    31     int M=(L+R)>>1;
    32     CDQ(L,M); CDQ(M,R);
    33     int i=M-1,j=R-1,cnt=0,x;
    34     while(i>=L&&j>=M)
    35     {
    36         if(a[i].x>a[j].x){
    37             b.update(a[i].w,a[i].p);
    38             que[++tl]=i; i--;
    39         }else{
    40             a[j].ans+=b.query(a[j].w-1);
    41             j--;
    42         }
    43     }
    44     while(i>=L) {i--;}
    45     while(j>=M) {a[j].ans+=b.query(a[j].w-1); j--;}
    46     while(tl) {x=que[tl--]; b.update(a[x].w,-a[x].p);}
    47      
    48     i=L,j=M,cnt=0;
    49     while(i<M&&j<R)
    50     {
    51         if(a[i].x<=a[j].x){
    52             b.update(a[i].w,a[i].p);
    53             que[++tl]=i; tmp[++cnt]=a[i]; i++;
    54         }else{
    55             a[j].ans+=b.query(ma)-b.query(a[j].w);
    56             tmp[++cnt]=a[j]; j++;
    57         }
    58     }
    59     while(i<M) {tmp[++cnt]=a[i]; i++;}
    60     while(j<R) {a[j].ans+=b.query(ma)-b.query(a[j].w); tmp[++cnt]=a[j]; j++;}
    61     while(tl) {x=que[tl--]; b.update(a[x].w,-a[x].p);}
    62  
    63     for(i=L;i<R;i++) a[i]=tmp[i-L+1];
    64 }
    65 int cmp(node s1,node s2){return s1.t<s2.t;}
    66  
    67 int main()
    68 {
    69     scanf("%d",&n);
    70     int i,j,x,y; ll ans=0;
    71     for(i=1;i<=n;i++) c[i]=a[i].w=gint();
    72     sort(c+1,c+n+1);
    73     ma=unique(c+1,c+n+1)-(c+1);
    74     for(i=1;i<=n;i++) a[i].w=lower_bound(c+1,c+ma+1,a[i].w)-c,q[i]=a[i].w;
    75     for(i=1;i<=n;i++) a[i].p=1,a[i].t=i,a[i].x=i;
    76     for(i=n;i>=1;i--) ans+=b.query(a[i].w-1),b.update(a[i].w,1);
    77     memset(b.s,0,sizeof(b.s));
    78     scanf("%d",&m); nn=n;
    79     for(i=n+1;i<=n+m;i++)
    80     {
    81         x=gint(); y=gint();
    82         a[++nn].p=-1,a[nn].t=nn,a[nn].x=x,a[nn].w=q[x];//,a[nn].id=i-n;
    83         a[++nn].p=-1,a[nn].t=nn,a[nn].x=y,a[nn].w=q[y];//a[nn].id=i-n;
    84         swap(q[x],q[y]);
    85         a[++nn].p=1,a[nn].t=nn,a[nn].x=x,a[nn].w=q[x];//a[nn].id=i-n;
    86         a[++nn].p=1,a[nn].t=nn,a[nn].x=y,a[nn].w=q[y];//a[nn].id=i-n;
    87     }
    88     CDQ(1,nn+1);
    89     sort(a+1,a+nn+1,cmp);
    90     printf("%lld
    ",ans);
    91     for(i=n+1;i<=nn;i+=4)
    92     {
    93         ans+=-a[i].ans-a[i+1].ans+a[i+2].ans+a[i+3].ans;
    94         printf("%lld
    ",ans);
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    关于web开发的一点理解
    如何通过Request.ServerVariables["HTTP_USER_AGENT"]获取客户端操作系统信息
    将图片转换为Base64
    asp.net 图片质量压缩(不改变尺寸)
    下载网路图片并保存在硬盘
    HTTP Content-type 对照表
    mssql 查询全部用户创建表 条数及占用空间大小(KB)
    幸运抽奖数据结构
    非UI线程和UI线程通信
    爬取淘宝“手机信息”
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10204929.html
Copyright © 2011-2022 走看看