[国家集训队2011]排队(魏铭)

Posted Mafia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[国家集训队2011]排队(魏铭)相关的知识,希望对你有一定的参考价值。

[国家集训队2011]排队(魏铭)

题目

排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。
红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足i<j且hi>hj的(i,j)数量。幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。

INPUT

第一行为一个正整数n,表示小朋友的数量;
第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;
第三行为一个正整数m,表示交换操作的次数;
以下m行每行包含两个正整数ai和bi­,表示交换位置ai与位置bi的小朋友。

OUTPUT

输出文件共m+1行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。

SAMPLE

INPUT

3
130 150 140
2
2 3
1 3

OUTPUT

1

0

3

解题报告

裸的动态逆序对

先用树状数组处理原序列的逆序对个数

线段树套平衡树查询排名(相当于查询区间有多少比他大的或小的),处理原贡献与交换后的贡献即可

注意交换两数对答案的影响

技术分享
  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cstdio>
  6 #include<ctime>
  7 using namespace std;
  8 inline int read(){
  9     int sum(0);
 10     char ch(getchar());
 11     for(;ch<0||ch>9;ch=getchar());
 12     for(;ch>=0&&ch<=9;sum=sum*10+(ch^48),ch=getchar());
 13     return sum;
 14 }
 15 #define get_size(x) (x?x->size:0)
 16 struct node{
 17     node *lch,*rch;
 18     int size,key,fix;
 19     node(int x=0):lch(NULL),rch(NULL),size(1),key(x),fix(rand()){}
 20     inline void pushup(){
 21         this->size=get_size(this->lch)+get_size(this->rch)+1;
 22     }
 23 }*tr[80005];
 24 inline void left_rotate(node *&x){
 25     node *tmp(x->rch);
 26     x->rch=tmp->lch;
 27     tmp->lch=x;
 28     x->pushup();
 29     tmp->pushup();
 30     x=tmp;
 31 }
 32 inline void right_rotate(node *&x){
 33     node *tmp(x->lch);
 34     x->lch=tmp->rch;
 35     tmp->rch=x;
 36     x->pushup();
 37     tmp->pushup();
 38     x=tmp;
 39 }
 40 inline void insert(node *&x,int v){
 41     if(!x){
 42         x=new node(v);
 43         return;
 44     }
 45     if(v<=x->key){
 46         insert(x->lch,v);
 47         x->pushup();
 48         if(x->lch->fix<x->fix)
 49             right_rotate(x);
 50     }
 51     else{
 52         insert(x->rch,v);
 53         x->pushup();
 54         if(x->rch->fix<x->fix)
 55             left_rotate(x);
 56     }
 57 }
 58 inline void del(node *&x,int v){
 59     if(x->key==v){
 60         if(x->lch&&x->rch){
 61             if(x->lch->fix<x->rch->fix){
 62                 right_rotate(x);
 63                 del(x->rch,v);
 64             }
 65             else{
 66                 left_rotate(x);
 67                 del(x->lch,v);
 68             }
 69         }
 70         else{
 71             node *tmp(NULL);
 72             if(x->lch)
 73                 tmp=x->lch;
 74             else
 75                 tmp=x->rch;
 76             delete x;
 77             x=tmp;
 78         }
 79     }
 80     else{
 81         if(v<=x->key)
 82             del(x->lch,v);
 83         else
 84             del(x->rch,v);
 85     }
 86     if(x)
 87         x->pushup();
 88 }
 89 inline int qmin(node *now,int x){
 90     int ret(0);
 91     while(now){
 92         if(x<=now->key)
 93             now=now->lch;
 94         else
 95             ret+=get_size(now->lch)+1,now=now->rch;
 96     }
 97     return ret;
 98 }
 99 inline int qmax(node *now,int x){
100     int ret(0);
101     while(now){
102         if(x>=now->key)
103             now=now->rch;
104         else
105             ret+=get_size(now->rch)+1,now=now->lch;
106     }
107     return ret;
108 }
109 int n,m,ans,size;
110 int a[20005],num[20005],bittree[20005];
111 inline int lowbit(int x){
112     return x&-x;
113 }
114 inline void update(int pos){
115     while(pos<=n){
116         ++bittree[pos];
117         pos+=lowbit(pos);
118     }
119 }
120 inline int sum(int pos){
121     int ret(0);
122     while(pos){
123         ret+=bittree[pos];
124         pos-=lowbit(pos);
125     }
126     return ret;
127 }
128 inline void build(int l,int r,int rt){
129     for(int i=l;i<=r;++i)
130         insert(tr[rt],a[i]);
131     if(l==r)return;
132     int mid((l+r)>>1);
133     build(l,mid,rt<<1);
134     build(mid+1,r,rt<<1|1);
135 }
136 inline void update(int pos,int las,int w,int l,int r,int rt){
137 //    cout<<pos<<‘ ‘<<l<<‘ ‘<<r<<‘ ‘<<w<<endl;
138     del(tr[rt],las);
139     insert(tr[rt],w);
140     if(l==r)return;
141     int mid((l+r)>>1);
142     if(pos<=mid)
143         update(pos,las,w,l,mid,rt<<1);
144     else
145         update(pos,las,w,mid+1,r,rt<<1|1);
146 }
147 inline int qmax(int ll,int rr,int w,int l,int r,int i){
148     if(ll<=l&&r<=rr)
149         return qmax(tr[i],w);
150     int mid((l+r)>>1),ret(0);
151     if(ll<=mid)
152         ret+=qmax(ll,rr,w,l,mid,i<<1);
153     if(mid<rr)
154         ret+=qmax(ll,rr,w,mid+1,r,i<<1|1);
155     return ret;
156 }
157 inline int qmin(int ll,int rr,int w,int l,int r,int i){
158     if(ll<=l&&r<=rr)
159         return qmin(tr[i],w);
160     int mid((l+r)>>1),ret(0);
161     if(ll<=mid)
162         ret+=qmin(ll,rr,w,l,mid,i<<1);
163     if(mid<rr)
164         ret+=qmin(ll,rr,w,mid+1,r,i<<1|1);
165     return ret;
166 }
167 int main(){
168     freopen("nt2011_queue.in","r",stdin);
169     freopen("nt2011_queue.out","w",stdout);
170     srand(time(NULL));
171     n=read();
172     for(int i=1;i<=n;++i)
173         num[i]=a[i]=read();
174     sort(num+1,num+n+1);
175     size=unique(num+1,num+n+1)-num-1;
176     for(int i=1;i<=n;++i){
177         a[i]=lower_bound(num+1,num+size+1,a[i])-num;
178         ans+=sum(n)-sum(a[i]);
179         update(a[i]);
180 //        cout<<i<<‘ ‘<<a[i]<<endl;
181     }
182     printf("%d\n",ans);
183     build(1,n,1);
184     m=read();
185     while(m--){
186         int x(read()),y(read());
187         if(a[x]==a[y]){
188             printf("%d\n",ans);
189             continue;
190         }
191         int tmp(0);
192         if(x>y)
193             swap(x,y);
194         if(a[x]>a[y])
195             tmp=1;
196         else
197             tmp=-1;
198         int tp1(0),tp2(0),tp3(0),tp4(0),tp5(0),tp6(0),tp7(0),tp8(0);
199         if(x!=1)tp1=qmax(1,x-1,a[x],1,n,1);
200         if(y!=1)tp2=qmax(1,y-1,a[y],1,n,1);
201         if(x!=n)tp3=qmin(x+1,n,a[x],1,n,1);
202         if(y!=n)tp4=qmin(y+1,n,a[y],1,n,1);
203         int gg1(a[x]),gg2(a[y]);
204         update(x,gg1,gg2,1,n,1),update(y,gg2,gg1,1,n,1);
205 //        cout<<"last array"<<endl;
206 //        for(int i=1;i<=n;++i)
207 //            cout<<a[i]<<‘ ‘;
208 //        cout<<endl;
209         swap(a[x],a[y]);
210         if(x!=1)tp5=qmax(1,x-1,a[x],1,n,1);
211         if(y!=1)tp6=qmax(1,y-1,a[y],1,n,1);
212         if(x!=n)tp7=qmin(x+1,n,a[x],1,n,1);
213         if(y!=n)tp8=qmin(y+1,n,a[y],1,n,1);
214 //        cout<<"now array"<<endl;
215 //        for(int i=1;i<=n;++i)
216 //            cout<<a[i]<<" ";
217 //        cout<<endl;
218 //        cout<<ans<<‘ ‘<<tp1<<‘ ‘<<tp2<<‘ ‘<<tp3<<‘ ‘<<tp4<<‘ ‘<<tp5<<‘ ‘<<tp6<<‘ ‘<<tp7<<" "<<tp8<<endl;
219         ans=ans-tp1-tp2-tp3-tp4+tp5+tp6+tp7+tp8+tmp;
220         printf("%d\n",ans);
221     }
222 }
View Code

222行1A我也很感动

以上是关于[国家集训队2011]排队(魏铭)的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ 2141][国家集训队 2011]排队 树状数组套平衡树

[luoguP1975] [国家集训队]排队(分块)

luogu1975 [国家集训队]排队

未能将测试运行“xxxx 2011-10-20 13:00:00”排队。您没有执行该操作的适当权限

求银行排队问题的解决方案?

如何通过代码设置片段标签?