BZOJ - 2141 排队 (动态逆序对,区间线段树套权值线段树)
交换两个数的位置,只有位于两个数之间的部分会受到影响,因此只需要考虑两个数之间有多少数对a[l]和a[r]产生的贡献发生了变化即可。
感觉像是个带修改的二维偏序问题。(修改点$(x,y)$的值,维护和查询位于$(x_1,y_1)$与$(x_2,y_2)$之间的点的个数)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=2e4+10,inf=0x3f3f3f3f; 5 int n,m,n2,rt[N<<2],ls[N*200],rs[N*200],sum[N*200],tot,a[N],b[N],ans; 6 #define lson (u<<1) 7 #define rson (u<<1|1) 8 #define mid ((l+r)>>1) 9 void upd2(int p,int x,int& u,int l=1,int r=n2) { 10 if(!u)u=++tot; 11 sum[u]+=x; 12 if(l==r)return; 13 p<=mid?upd2(p,x,ls[u],l,mid):upd2(p,x,rs[u],mid+1,r); 14 } 15 int qry2(int L,int R,int& u,int l=1,int r=n2) { 16 if(l>=L&&r<=R)return sum[u]; 17 if(l>R||r<L)return 0; 18 return qry2(L,R,ls[u],l,mid)+qry2(L,R,rs[u],mid+1,r); 19 } 20 void upd(int p,int x,int dx,int u=1,int l=1,int r=n) { 21 upd2(x,dx,rt[u]); 22 if(l==r)return; 23 p<=mid?upd(p,x,dx,lson,l,mid):upd(p,x,dx,rson,mid+1,r); 24 } 25 int qry(int L,int R,int L2,int R2,int u=1,int l=1,int r=n) { 26 if(l>=L&&r<=R)return qry2(L2,R2,rt[u]); 27 if(l>R||r<L)return 0; 28 return qry(L,R,L2,R2,lson,l,mid)+qry(L,R,L2,R2,rson,mid+1,r); 29 } 30 int main() { 31 scanf("%d",&n); 32 for(int i=1; i<=n; ++i)scanf("%d",&a[i]); 33 for(int i=1; i<=n; ++i)b[i]=a[i]; 34 sort(b+1,b+1+n),n2=unique(b+1,b+1+n)-(b+1); 35 for(int i=1; i<=n; ++i)a[i]=lower_bound(b+1,b+1+n2,a[i])-b; 36 for(int i=1; i<=n; ++i)ans+=qry(1,n,a[i]+1,n2),upd(i,a[i],1); 37 printf("%d\n",ans); 38 scanf("%d",&m); 39 while(m--) { 40 int l,r; 41 scanf("%d%d",&l,&r); 42 if(l>r)swap(l,r); 43 if(l==r||a[l]==a[r]); 44 else { 45 if(a[l]<a[r])ans+=qry(l+1,r-1,a[l]+1,a[r])+qry(l+1,r-1,a[l],a[r]-1)+1; 46 else ans-=qry(l+1,r-1,a[r]+1,a[l])+qry(l+1,r-1,a[r],a[l]-1)+1; 47 upd(l,a[l],-1),upd(l,a[r],1); 48 upd(r,a[r],-1),upd(r,a[l],1); 49 swap(a[l],a[r]); 50 } 51 printf("%d\n",ans); 52 } 53 return 0; 54 }
还有理论上能够AC的线段树套treap的版本,可惜常数太大TLE了~QAQ~
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=2e4+10,inf=0x3f3f3f3f; 5 int n,m,n2,rt[N<<2],ch[N*30][2],val[N*30],siz[N*30],rd[N*30],tot,a[N],b[N],ans; 6 #define lson (u<<1) 7 #define rson (u<<1|1) 8 #define mid ((l+r)>>1) 9 void pu(int u) {siz[u]=siz[ch[u][0]]+siz[ch[u][1]]+1;} 10 int newnode(int x) {int u=++tot; ch[u][0]=ch[u][1]=0,siz[u]=1,val[u]=x,rd[u]=rand(); return u;} 11 void rot(int& u,int f) { 12 int v=ch[u][f]; 13 ch[u][f]=ch[v][f^1],ch[v][f^1]=u; 14 pu(u),pu(v),u=v; 15 } 16 void ins(int& u,int x) { 17 if(!u) {u=newnode(x); return;} 18 int f=x>val[u]; 19 ins(ch[u][f],x); 20 if(rd[ch[u][f]]>rd[u])rot(u,f); 21 if(u)pu(u); 22 } 23 void del(int& u,int x) { 24 if(!u)return; 25 if(val[u]==x) { 26 if(!ch[u][0]||!ch[u][1])u=ch[u][0]|ch[u][1]; 27 else { 28 int f=rd[ch[u][1]]>rd[ch[u][0]]; 29 rot(u,f),del(ch[u][f^1],x); 30 } 31 } else del(ch[u][x>val[u]],x); 32 if(u)pu(u); 33 } 34 int lb(int u,int x) { 35 int ret=0; 36 for(; u; u=ch[u][x>val[u]])if(val[u]>=x)ret=val[u]; 37 return ret; 38 } 39 int ub(int u,int x) { 40 int ret=0; 41 for(; u; u=ch[u][x>=val[u]])if(val[u]>x)ret=val[u]; 42 return ret; 43 } 44 int rnk(int u,int x) { 45 int ret=0; 46 for(; u; u=ch[u][x>val[u]])if(x>val[u])ret+=siz[ch[u][0]]+1; 47 return ret+1; 48 } 49 int sum(int u,int l,int r) {return l>r?0:rnk(u,ub(u,r))-rnk(u,lb(u,l));} 50 void upd(int p,int x,int dx,int u=1,int l=1,int r=n) { 51 dx==1?ins(rt[u],x):del(rt[u],x); 52 if(l==r)return; 53 p<=mid?upd(p,x,dx,lson,l,mid):upd(p,x,dx,rson,mid+1,r); 54 } 55 int qry(int L,int R,int L2,int R2,int u=1,int l=1,int r=n) { 56 if(l>=L&&r<=R)return sum(rt[u],L2,R2); 57 if(l>R||r<L)return 0; 58 return qry(L,R,L2,R2,lson,l,mid)+qry(L,R,L2,R2,rson,mid+1,r); 59 } 60 void build(int u=1,int l=1,int r=n) { 61 ins(rt[u],~inf),ins(rt[u],inf); 62 if(l==r)return; 63 build(lson,l,mid),build(rson,mid+1,r); 64 } 65 int main() { 66 srand(time(0)); 67 scanf("%d",&n); 68 for(int i=1; i<=n; ++i)scanf("%d",&a[i]); 69 for(int i=1; i<=n; ++i)b[i]=a[i]; 70 sort(b+1,b+1+n),n2=unique(b+1,b+1+n)-(b+1); 71 for(int i=1; i<=n; ++i)a[i]=lower_bound(b+1,b+1+n2,a[i])-b; 72 build(); 73 for(int i=1; i<=n; ++i)ans+=qry(1,n,a[i]+1,n2),upd(i,a[i],1); 74 printf("%d\n",ans); 75 scanf("%d",&m); 76 while(m--) { 77 int l,r; 78 scanf("%d%d",&l,&r); 79 if(l>r)swap(l,r); 80 if(l==r||a[l]==a[r]); 81 else { 82 if(a[l]<a[r])ans+=qry(l+1,r-1,a[l]+1,a[r])+qry(l+1,r-1,a[l],a[r]-1)+1; 83 else ans-=qry(l+1,r-1,a[r]+1,a[l])+qry(l+1,r-1,a[r],a[l]-1)+1; 84 upd(l,a[l],-1),upd(l,a[r],1); 85 upd(r,a[r],-1),upd(r,a[l],1); 86 swap(a[l],a[r]); 87 } 88 printf("%d\n",ans); 89 } 90 return 0; 91 }
后续:我把treap的区间求和方式改了稍微改了一下,卡时过掉了~~
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=2e4+10,inf=0x3f3f3f3f; 5 int n,m,n2,rt[N<<2],ch[N*30][2],val[N*30],siz[N*30],rd[N*30],tot,a[N],b[N],ans; 6 #define lson (u<<1) 7 #define rson (u<<1|1) 8 #define mid ((l+r)>>1) 9 void pu(int u) {siz[u]=siz[ch[u][0]]+siz[ch[u][1]]+1;} 10 int newnode(int x) {int u=++tot; ch[u][0]=ch[u][1]=0,siz[u]=1,val[u]=x,rd[u]=rand(); return u;} 11 void rot(int& u,int f) { 12 int v=ch[u][f]; 13 ch[u][f]=ch[v][f^1],ch[v][f^1]=u; 14 pu(u),pu(v),u=v; 15 } 16 void ins(int& u,int x) { 17 if(!u) {u=newnode(x); return;} 18 int f=x>val[u]; 19 ins(ch[u][f],x); 20 if(rd[ch[u][f]]>rd[u])rot(u,f); 21 if(u)pu(u); 22 } 23 void del(int& u,int x) { 24 if(!u)return; 25 if(val[u]==x) { 26 if(!ch[u][0]||!ch[u][1])u=ch[u][0]|ch[u][1]; 27 else { 28 int f=rd[ch[u][1]]>rd[ch[u][0]]; 29 rot(u,f),del(ch[u][f^1],x); 30 } 31 } else del(ch[u][x>val[u]],x); 32 if(u)pu(u); 33 } 34 int lb(int u,int x) { 35 int ret=0; 36 for(; u; u=ch[u][x>val[u]])if(x>val[u])ret+=siz[ch[u][0]]+1; 37 return ret; 38 } 39 int ub(int u,int x) { 40 int ret=0; 41 for(; u; u=ch[u][x>=val[u]])if(x>=val[u])ret+=siz[ch[u][0]]+1; 42 return ret; 43 } 44 int sum(int u,int l,int r) {return ub(u,r)-lb(u,l);} 45 void upd(int p,int x,int dx,int u=1,int l=1,int r=n) { 46 dx==1?ins(rt[u],x):del(rt[u],x); 47 if(l==r)return; 48 p<=mid?upd(p,x,dx,lson,l,mid):upd(p,x,dx,rson,mid+1,r); 49 } 50 int qry(int L,int R,int L2,int R2,int u=1,int l=1,int r=n) { 51 if(l>=L&&r<=R)return sum(rt[u],L2,R2); 52 if(l>R||r<L)return 0; 53 return qry(L,R,L2,R2,lson,l,mid)+qry(L,R,L2,R2,rson,mid+1,r); 54 } 55 int main() { 56 srand(time(0)); 57 scanf("%d",&n); 58 for(int i=1; i<=n; ++i)scanf("%d",&a[i]); 59 for(int i=1; i<=n; ++i)b[i]=a[i]; 60 sort(b+1,b+1+n),n2=unique(b+1,b+1+n)-(b+1); 61 for(int i=1; i<=n; ++i)a[i]=lower_bound(b+1,b+1+n2,a[i])-b; 62 for(int i=1; i<=n; ++i)ans+=qry(1,n,a[i]+1,n2),upd(i,a[i],1); 63 printf("%d\n",ans); 64 scanf("%d",&m); 65 while(m--) { 66 int l,r; 67 scanf("%d%d",&l,&r); 68 if(l>r)swap(l,r); 69 if(l==r||a[l]==a[r]); 70 else { 71 if(a[l]<a[r])ans+=qry(l+1,r-1,a[l]+1,a[r])+qry(l+1,r-1,a[l],a[r]-1)+1; 72 else ans-=qry(l+1,r-1,a[r]+1,a[l])+qry(l+1,r-1,a[r],a[l]-1)+1; 73 upd(l,a[l],-1),upd(l,a[r],1); 74 upd(r,a[r],-1),upd(r,a[l],1); 75 swap(a[l],a[r]); 76 } 77 printf("%d\n",ans); 78 } 79 return 0; 80 }