This problem is a dynamic reverse order, is essentially a query interval ranking
Just hit a. [Cqoi 2011] Dynamic Reverse -order the line of the tree-set balance tree, the code is as follows:
#include <iostream> #include <cstdio> #include <cstring>using namespace std; #define POS (i,a,b) for ( int i= (a); i<= (b); i++) #define N 101000#include<cstdlib> #define LL Long long#define LC (x) (x->ch[0]) #define RC (x) (x->ch[1]) #define SIZE (x) ((x)? ( X->size): 0) struct treap{treap *ch[2]; int key,v; LL size; treap (int x=0) {v=x;ch[0]=ch[1]=null;size=1;key=rand (); }}*root[n*4];void Turn (treap *&rt,int d) {treap *t=rt->ch[d^1]; rt->ch[d^1]=t->ch[d]; Rt->size=size (LC (RT)) +size (RC (RT))) +1; t->ch[d]=rt; T->size=size (LC (T)) +size (RC (t)) +1; rt=t;} void Insert (Treap *&rt,int x) {if (rt==null) {rt=new treap (x); return; } int D=rt->v < x; Insert (RT->CH[D],X); if (Rt->ch[d]->key < Rt->key) Turn (rt,d^1); if (RT) Rt->size=size (LC (RT)) +size (RC (RT))) +1; void del (treap *&rt,int x) {if (rt->v = = x) {if (LC (RT) &&RC (RT)) {int d=lc (RT)->key & Lt RC (RT)->key; Turn (rt,d);d El (rt->ch[d],x); } else{treap *t=null; if (LC (RT)) T=LC (RT); ELSE T=RC (RT); Delete rt;rt=t; }} else{int d=rt->v < x; Del (RT->CH[D],X); } if (RT) Rt->size=size (LC (RT)) +size (RC (RT))) +1;} int A[n],pos[n];int n,m;void Build (int l,int R,int RT) {POS (i,l,r) Insert (Root[rt],a[i]); if (l==r) return; int mid= (L+R) >>1; Build (l,mid,rt<<1); Build (mid+1,r,rt<<1|1);} LL Pai (treap *&rt,int x) {if (!RT) return 0; if (rt->v >= x) return PAI (LC (RT), x); else return size (LC (RT)) +1+pai (RC (RT), x);} LL query (int flag,int xl,int xr,int l,int r,int num,int RT) {if (L>=XL&&R<=XR) {if (flag) return Pai (Root[rt],num); else return size (Root[rt])-pai (root[rt],num); } int mid= (L+R) >>1; int res (0); if (xl<=mid) res+=query (flag,xl,xr,l,mid,num,rt<<1); if (Xr>mid) Res+=query (fLAG,XL,XR,MID+1,R,NUM,RT<<1|1); return res;} void del (int pos,int x,int l,int r,int RT) {Del (root[rt],x); if (l==r) return; int mid= (L+R) >>1; if (pos<=mid) Del (pos,x,l,mid,rt<<1); else Del (pos,x,mid+1,r,rt<<1|1);} LL ans;inline int Read () {int sum (0); char Ch=getchar (); while (ch< ' 0 ' | | Ch> ' 9 ') Ch=getchar (); while (ch>= ' 0 ' &&ch<= ' 9 ') {sum=sum*10+ch-' 0 '; Ch=getchar (); } return sum;} int lowbit (int x) {return x& (-X);} int c[n];void Add (int x,int num) {while (x<=n) {c[x]+=num;x+=lowbit (x); }}LL tot (int x) {LL res (0); while (x>0) {res+=c[x];x-=lowbit (x); } return res; int main () {n=read (); M=read (); POS (i,1,n) {a[i]=read (); Pos[a[i]]=i; } build (1,n,1); POS (i,1,n) {Ans+=i-1-tot (a[i]-1); Add (a[i],1); } POS (i,1,m) {printf ("%lld\n", ans); int X;x=read (); if (pos[x]+1<=n) ans-=query (1,pos[x]+1,n,1,n,x,1); if (pos[x]-1>=1) ans-=query (0,1,pos[x]-1,1,n,x,1); Del (pos[x],x,1,n,1); } return 0;}
But the constant is too large, leading to cogs on the card half a day often did not past the last point, only in the intranet a dropped (Praise the network evaluation machine)
For this problem, chose the original did not hit the tree array set of balance tree (in fact, the same is the same)
If we were to exchange the position of A and B (a<b), then the answer would have an effect on the [a+1,b-1] interval.
ans=ans-(number of >b in interval) + (number of <b within interval)-(number of <a in interval) + (number of >a within interval)
And then consider the contribution of the size of a and B itself.
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cstdlib > #include <algorithm>using namespace std; #define POS (I,A,B) for (int i= (a); i<= (b); i++) #define N 20100# Define LC (X) (x->ch[0]) #define RC (x) (x->ch[1]) #define SIZE (x) ((x)? ( X->size): 0) int n,m;int a[n];struct treap{treap *ch[2]; int key,v,size; treap (int x=0) {ch[0]=ch[1]=null;key=rand (); size=1;v=x;}} *root[n];void pushup (treap *&rt) {rt->size=size (LC (RT)) +size (RC (RT)) +1;} void Turn (treap *&rt,int d) {treap *t=rt->ch[d^1]; Rt->ch[d^1]=t->ch[d];p ushup (RT); T->ch[d]=rt;pushup (t); rt=t;} void Insert (Treap *&rt,int x) {if (!rt) {rt=new treap (x); Return } int D=rt->v < x; Insert (RT->CH[D],X); if (Rt->ch[d]->key < Rt->key) Turn (rt,d^1); if (RT) pushup (RT);} void del (treap *&rt,int x) {if (rt->v==x) {if (LC (RT) &&RC (RT)) {int d=lc (RT)->keY < RC (RT)->key; Turn (rt,d);d El (rt->ch[d],x); } else{treap *t; if (LC (RT)) T=LC (RT); ELSE T=RC (RT); Delete rt;rt=t; }} else{int d=rt->v < x; Del (RT->CH[D],X); } if (RT) pushup (RT);} int lowbit (int x) {return x& (-X);} int ans;void Add (int x,int num,int flag) {while (x<=n) {if (flag) insert (root[x],num); Else del (root[x],num); X+=lowbit (x); }}int pai_min (treap *&rt,int num) {if (!RT) return 0; if (rt->v >= num) return Pai_min (LC (RT), NUM); else return size (LC (RT)) +1+pai_min (RC (RT), num);} int Pai_max (treap *&rt,int num) {if (!RT) return 0; if (Rt->v > num) return size (RC (RT)) +1+pai_max (LC (RT), NUM); else return Pai_max (RC (RT), num);} int tot_max (int x,int num) {int sum (0); while (x>0) {Sum+=pai_max (root[x],num); X-=lowbit (x); } return sum;} int tot_min (int x,int num) {int sum (0); while (x>0) {sum+=pai_min (root[x],num); X-=lowbit (x); } return sum;} vector<int> b;int findx (int x) {return lower_bound (B.begin (), B.end (), x)-b.begin () +1;} int main () {scanf ("%d", &n); POS (i,1,n) {scanf ("%d", &a[i]); B.push_back (A[i]); } sort (B.begin (), B.end ()); B.erase (Unique (B.begin (), B.end ()), B.end ()); POS (i,1,n) {a[i]=findx (a[i]); add (i,a[i],1); } POS (I,1,n) {Ans+=tot_max (i-1,a[i]); } scanf ("%d", &m); printf ("%d\n", ans); POS (i,1,m) {int x,y;scanf ("%d%d", &x,&y); if (x>y) swap (x, y); Ans-=tot_max (Y-1,a[y])-tot_max (X,a[y]); Ans+=tot_min (Y-1,a[y])-tot_min (X,a[y]); Ans-=tot_min (Y-1,a[x])-tot_min (x,a[x]); Ans+=tot_max (Y-1,a[x])-tot_max (x,a[x]); if (A[x]>a[y]) ans--; else if (a[x]<a[y]) ans++; Add (x,a[x],0); add (x,a[y],1); Add (y,a[y],0); add (y,a[x],1); Swap (a[x],a[y]); printf ("%d\n", ans); } RetuRN 0;}
I would like to commemorate this type of tree nesting tree introduction
[Bzoj 2141] [National Training Team 2011] Queue Tree Array set balance tree