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 }

 

posted @ 2019-04-12 16:01  jrltx  阅读(200)  评论(0编辑  收藏  举报