[国家集训队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 3OUTPUT
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 }
222行1A我也很感动
以上是关于[国家集训队2011]排队(魏铭)的主要内容,如果未能解决你的问题,请参考以下文章
[BZOJ 2141][国家集训队 2011]排队 树状数组套平衡树