bzoj 2141: 排队

Posted ws_ccd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2141: 排队相关的知识,希望对你有一定的参考价值。

就是求个动态区间逆序对??是不是和GTY文艺妹子差不多??哦,不是,,,

这个题的话,可以发现的是,每次交换只会对区间内的数产生影响,所以就是求一下区间内比这个L(区间左端点)大的,小的,(减小,加大)比R(区间右端点)大的,小的,(减大,加小),然后把连个数换一下就就行了。。我记得是这样。。而且这个sb题也是调了好久、、、

  1 #include<bits/stdc++.h>
  2 #define N 100005
  3 #define LL long long
  4 #define inf 0x3f3f3f3f
  5 using namespace std;
  6 inline int ra()
  7 {
  8     int x=0,f=1; char ch=getchar();
  9     while (ch<0 || ch>9) {if (ch==-) f=-1; ch=getchar();}
 10     while (ch>=0 && ch<=9) {x=x*10+ch-0; ch=getchar();}
 11     return x*f;
 12 }
 13 const int M=5000005;
 14 int a[N],sz,n,ans;
 15 int ls[M],rs[M],s[M],w[M],v[M],rnd[M],root[M];
 16 void update(int k){s[k]=s[ls[k]]+s[rs[k]]+w[k];}
 17 void rturn(int &k){int t=ls[k]; ls[k]=rs[t]; rs[t]=k; s[t]=s[k]; update(k); k=t;}
 18 void lturn(int &k){int t=rs[k]; rs[k]=ls[t]; ls[t]=k; s[t]=s[k]; update(k); k=t;}
 19 void insert(int &k, int num)
 20 {
 21     if (!k) {
 22         k=++sz; w[k]=s[k]=1; ls[k]=rs[k]=0; v[k]=num; rnd[k]=rand(); return;
 23     }
 24     s[k]++;
 25     if (num==v[k]) w[k]++;
 26     else if (num<v[k]) {insert(ls[k],num); if (rnd[ls[k]]<rnd[k]) rturn(k); }
 27     else {insert(rs[k],num); if (rnd[rs[k]]<rnd[k]) lturn(k);}
 28 }
 29 void del(int &k, int num)
 30 {
 31     if (v[k]==num)
 32     {
 33         if (w[k]>1) {s[k]--; w[k]--; return;}
 34         if (ls[k]*rs[k]==0) k=ls[k]+rs[k];
 35         else {if (rnd[ls[k]]<rnd[rs[k]]) rturn(k), del(k,num);
 36                 else lturn(k),del(k,num);
 37         }
 38     }
 39     else if (num<v[k]) del(ls[k],num),s[k]--;
 40         else del(rs[k],num),s[k]--;
 41 }
 42 void build(int k, int l, int r, int x, int num)
 43 {
 44     insert(root[k],num);
 45     if (l==r) return;
 46     int mid=l+r>>1;
 47     if (x<=mid) build(k<<1,l,mid,x,num);
 48     else build(k<<1|1,mid+1,r,x,num);
 49 }
 50 int find1(int k, int num)
 51 {
 52     if (!k) return 0;
 53     if (num==v[k]) return s[ls[k]];
 54     else if (num<v[k]) return find1(ls[k],num);
 55     else return w[k]+s[ls[k]]+find1(rs[k],num);
 56 }
 57 int ask1(int k ,int l, int r, int x, int y, int num)
 58 {
 59     if (l>r || x>y) return 0; 
 60     if (l==x && y==r) return find1(root[k],num);
 61     int mid=l+r>>1;
 62     if (y<=mid) return ask1(k<<1,l,mid,x,y,num);
 63     else if (x>mid) return ask1(k<<1|1,mid+1,r,x,y,num);
 64     else return ask1(k<<1,l,mid,x,mid,num)+ask1(k<<1|1,mid+1,r,mid+1,y,num);
 65 }
 66 int find(int k, int num)
 67 {
 68     if (!k) return 0;
 69     if (num==v[k]) return s[ls[k]]+w[k];
 70     else if (num<v[k]) return find(ls[k],num);
 71     else return w[k]+s[ls[k]]+find(rs[k],num);
 72 }
 73 int ask(int k ,int l, int r, int x, int y, int num)
 74 {
 75     if (l>r || x>y) return 0; 
 76     if (l==x && y==r) return find(root[k],num);
 77     int mid=l+r>>1;
 78     if (y<=mid) return ask(k<<1,l,mid,x,y,num);
 79     else if (x>mid) return ask(k<<1|1,mid+1,r,x,y,num);
 80     else return ask(k<<1,l,mid,x,mid,num)+ask(k<<1|1,mid+1,r,mid+1,y,num);
 81 }
 82 void change(int k, int l, int r, int pos, int old, int num)
 83 {
 84     del(root[k],old); insert(root[k],num);
 85     if (l==r) return;
 86     int mid=l+r>>1;
 87     if (pos<=mid) change(k<<1,l,mid,pos,old,num);
 88     else change(k<<1|1,mid+1,r,pos,old,num);
 89 }
 90 int main()
 91 {
 92     n=ra(); 
 93     for (int i=1; i<=n; i++) 
 94     {
 95         a[i]=ra();
 96         build(1,1,n,i,a[i]);
 97         ans+=(i-1-ask(1,1,n,1,i-1,a[i]));
 98     //    cout<<(i-1-ask(1,1,n,1,i-1,a[i]))<<endl;
 99     }
100     printf("%d\n",ans);
101     int m=ra();
102     while (m--)
103     {
104         int x=ra(),y=ra();
105         if (x>y) swap(x,y);
106         if (a[x]>a[y]) ans--; if (a[x]<a[y]) ans++;
107         ans+=ask(1,1,n,x+1,y-1,a[y])+ask1(1,1,n,x+1,y-1,a[y])-ask(1,1,n,x+1,y-1,a[x])-ask1(1,1,n,x+1,y-1,a[x]);
108         change(1,1,n,x,a[x],a[y]); change(1,1,n,y,a[y],a[x]);
109         swap(a[x],a[y]);
110     //    for (int i=1; i<=n; i++) printf("%d ",a[i]); cout<<endl;
111         printf("%d\n",ans);
112     }
113     return 0;
114 }

 

以上是关于bzoj 2141: 排队的主要内容,如果未能解决你的问题,请参考以下文章

Bzoj 2141: 排队 分块,逆序对,树状数组

BZOJ 2141 排队(块套树,分块,树状数组)BZOJ修复工程

BZOJ 2141 排队(块套树,分块,树状数组)BZOJ修复工程

bzoj 2141: 排队

[BZOJ2141]排队

BZOJ 2141: 排队 CDQ分治+bit