【bzoj2141】排队 [国家集训队2011]排队(树套树)

题目描述

排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。

红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足i<j且hi>hj的(i,j)数量。

幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。

题解

  新技能get

  树状数组+动态开点线段树

  具体看代码(因为我讲不来)

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=20005;
 7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 8 char buf[1<<21],*p1=buf,*p2=buf;
 9 inline int read(){
10     #define num ch-'0'
11     char ch;bool flag=0;int res;
12     while(!isdigit(ch=getc()))
13     (ch=='-')&&(flag=true);
14     for(res=num;isdigit(ch=getc());res=res*10+num);
15     (flag)&&(res=-res);
16     #undef num
17     return res;
18 }
19 char sr[1<<21],z[20];int C=-1,Z;
20 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
21 inline void print(int x){
22     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
23     while(z[++Z]=x%10+48,x/=10);
24     while(sr[++C]=z[Z],--Z);sr[++C]='\n';
25 }
26 struct node{
27     int v,id;
28     inline bool operator <(const node &b)const{return v<b.v;}
29 }a[N];
30 int n,m,x,y,tot,ans,b[N],c[N];
31 inline void add(int x){
32     for(;x<=n;x+=x&-x) ++c[x];
33 }
34 inline int sum(int x){
35     int res=0;
36     for(;x;x-=x&-x) res+=c[x];
37     return res;
38 }
39 int cnt,rt[N],v[N*400],L[N*400],R[N*400];
40 void insert(int &u,int l,int r,int x,int k){
41     if(!u) u=++cnt;v[u]+=k;
42     if(l==r) return;int mid=l+r>>1;
43     if(x<=mid) insert(L[u],l,mid,x,k);
44     else insert(R[u],mid+1,r,x,k);
45 }
46 void push(int x,int y,int k){
47     for(;x<=n;x+=x&-x) insert(rt[x],1,n,y,k);
48 }
49 int Query(int u,int l,int r,int ql,int qr){
50     if(!u) return 0;
51     if(ql<=l&&qr>=r) return v[u];
52     int mid=l+r>>1;
53     int res=0;
54     if(ql<=mid) res+=Query(L[u],l,mid,ql,qr);
55     if(qr>mid) res+=Query(R[u],mid+1,r,ql,qr);
56     return res;
57 }
58 int query(int l,int r,int ql,int qr){
59     if(l>r||ql>qr) return 0;
60     int sum=0;--l;
61     for(;r;r-=r&-r) sum+=Query(rt[r],1,n,ql,qr);
62     for(;l;l-=l&-l) sum-=Query(rt[l],1,n,ql,qr);
63     return sum;
64 }
65 int main(){
66     //freopen("testdata.in","r",stdin);
67     n=read();
68     for(int i=1;i<=n;++i) a[i]=(node){read(),i};
69     sort(a+1,a+1+n);
70     for(int i=1;i<=n;++i){
71         if(a[i].v!=a[i-1].v) ++tot;
72         b[a[i].id]=tot;
73     }
74     for(int i=n;i;--i) ans+=sum(b[i]-1),add(b[i]);
75     for(int i=1;i<=n;++i) push(i,b[i],1);
76     m=read(),print(ans);
77     while(m--){
78         int x=read(),y=read();
79         if(x>y) swap(x,y);
80         ans+=query(x+1,y-1,1,b[y]-1);
81         ans-=query(x+1,y-1,b[y]+1,n);
82         ans+=query(x+1,y-1,b[x]+1,n);
83         ans-=query(x+1,y-1,1,b[x]-1);
84         if(b[x]>b[y]) --ans;
85         if(b[x]<b[y]) ++ans;
86         push(x,b[x],-1),push(y,b[y],-1);
87         push(y,b[x],1),push(x,b[y],1);
88         swap(b[x],b[y]);
89         print(ans);
90     }
91     Ot();
92     return 0;
93 }

 

posted @ 2018-08-30 15:18  bztMinamoto  阅读(254)  评论(0编辑  收藏  举报
Live2D