BZOJ - 3295 动态逆序对 (树状数组套treap)

题目链接

思路和bzoj2141差不多,不过这道题的数据更强一些,线段树套treapT了,树状数组套treap卡过~~

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=1e5+10,inf=0x3f3f3f3f;
 5 int rt[N],n,m,n2,ch[N*30][2],val[N*30],siz[N*30],rd[N*30],tot,a[N],b[N];
 6 ll ans;
 7 void pu(int u) {siz[u]=siz[ch[u][0]]+siz[ch[u][1]]+1;}
 8 int newnode(int x) {int u=++tot; siz[u]=1,val[u]=x,rd[u]=rand(),ch[u][0]=ch[u][1]=0; return u;}
 9 void rot(int& u,int f) {
10     int v=ch[u][f];
11     ch[u][f]=ch[v][f^1],ch[v][f^1]=u;
12     pu(u),pu(v),u=v;
13 }
14 void ins(int& u,int x) {
15     if(!u) {u=newnode(x); return;}
16     int f=x>val[u];
17     ins(ch[u][f],x);
18     if(rd[ch[u][f]]>rd[u])rot(u,f);
19     if(u)pu(u);
20 }
21 void del(int& u,int x) {
22     if(val[u]==x) {
23         if(!ch[u][0]||!ch[u][1])u=ch[u][0]|ch[u][1];
24         else {
25             int f=rd[ch[u][1]]>rd[ch[u][0]];
26             rot(u,f),del(ch[u][f^1],x);
27         }
28     } else del(ch[u][x>val[u]],x);
29     if(u)pu(u);
30 }
31 int ask(int u,int x) {
32     int ret=0;
33     for(; u; u=ch[u][x>=val[u]])if(x>=val[u])ret+=siz[ch[u][0]]+1;
34     return ret;
35 }
36 void add(int u,int x,int dx) {for(; u<=n; u+=u&-u)dx==1?ins(rt[u],x):del(rt[u],x);}
37 int get1(int u,int x) {int ret=0; for(; u; u-=u&-u)ret+=ask(rt[u],x-1); return ret;}
38 int get2(int u,int x) {int ret=0; for(; u; u-=u&-u)ret+=siz[rt[u]]-ask(rt[u],x); return ret;}
39 
40 int main() {
41     srand(time(0));
42     scanf("%d%d",&n,&m),n2=n;
43     for(int i=1; i<=n; ++i)scanf("%d",&a[i]);
44     for(int i=1; i<=n; ++i)b[a[i]]=i;
45     for(int i=n; i>=1; --i)ans+=get1(n,a[i]),add(i,a[i],1);
46     while(m--) {
47         printf("%lld\n",ans);
48         int x;
49         scanf("%d",&x);
50         int t1=get2(b[x]-1,x),t2=get1(n,x)-get1(b[x],x);
51         ans-=t1+t2;
52         add(b[x],x,-1);
53         n2--;
54     }
55     return 0;
56 }

 

posted @ 2019-04-12 21:18  jrltx  阅读(133)  评论(0编辑  收藏  举报