[国家集训队2011]排队(魏铭)
生活随笔
收集整理的這篇文章主要介紹了
[国家集训队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
",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
",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
",ans);
221 }
222 }
View Code
222行1A我也很感動
總結
以上是生活随笔為你收集整理的[国家集训队2011]排队(魏铭)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记录一次查询log的经历
- 下一篇: WiFi(802.11)基础