【noi.ac #1771】A. ball

題目

Description
給出 n 條平行的縱向軌道 ,有 m 根橫向的短棒支在一些相鄰軌道上。如果在某個軌道頂端釋放一個小球,它會沿着這個軌道一直下落,一旦碰到短棒就會沿着短棒滾到相鄰軌道並繼續下落。

爲了增加難度,每次可能會拿走某些短棒,或者詢問一個從 x 號軌道下落的小球最終落到哪個軌道。

Input
第一行讀入兩個整數 n,m (2≤n≤5×105,0≤m≤5×105),分別表示軌道的數量和短棒的數量。 第二行讀入 m 個整數,第 i 個整數記爲 idi (1≤idi<n) ,表示從上到下第 i 根短棒位於編號爲 idi 和 idi+1 的軌道之間。 第三行讀入一個整數 Q (1≤Q≤5×105),表示操作總數。 接下來讀入 Q 行,每行讀入兩個整數 opt,x。如果 opt=1,表示拿走從上到下的第 x (1≤x≤m) 根短棒。保證不會拿走重複的木棒。如果 opt=2,詢問一個初始從軌道 x (1≤x≤n) 下落的小球最終落到了哪個軌道。

Output
對於每一個 opt=2 的操作,輸出最終到達的軌道編號。

Sample Input
6 5
2 1 5 3 2
10
2 1
2 2
2 6
1 3
2 6
2 3
1 1
2 2
2 3
2 4
Sample Output
3
4
5
6
1
1
4
2
Hint
一共有 10 組測試數據,數據有梯度。

測試點編號 特殊性質
1,2,3 m,Q≤1000
4,5 沒有拿走短棒的操作
6,7 n,m,Q≤50000
8 n=m=Q=100000,初始短棒位置、拿走的短棒、詢問的軌道都在其可行範圍內均勻隨機
9,10 無特殊約定

思路

測試點 1,2,3

每次詢問時從高到低枚舉每一根短棒,如果在一側就變成另一側。 效率:O(mQ)O(mQ) 。注意nn可能會很大。

測試點 4,5

因爲沒有修改,可以考慮提前算出所有的答案。 一開始設 ansi=ians_i=i,從低到高觀察每一根木棒:如果它位於 x..x+1x..x+1 之間,相當於交換 ansxans_xansyans_y 的值。預處理完後就可以直接輸出答案了。

效率 O(m+Q)O(m+Q)

代碼

#include<bits/stdc++.h>
using namespace std;
const int N=4e6+77;
int s[N][2],f[N],a[N],yjy[N],n,m,cnt;
void rotate(int x){
	int y=f[x],z=f[y],w=s[y][0]==x;
	if (s[y][w^1]=s[x][w]) f[s[x][w]]=y;
	if (z) s[z][s[z][1]==y]=x;
	s[x][w]=y;f[y]=x;f[x]=z;
}
void splay(int x){
	while (f[x]){
		int y=f[x],z=f[y];
		if (z)
			rotate(((s[z][1]==y)^(s[y][1]==x))?x:y);
		rotate(x);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++)
		scanf("%d",&a[i]);
	cnt=1;
	for (int i=m;i;i--){
		++cnt;
		if (f[cnt]=yjy[a[i]])
			s[yjy[a[i]]][1]=cnt;
		yjy[a[i]]=cnt^1;
	
		++cnt;
		if (f[cnt]=yjy[a[i]+1])
			s[yjy[a[i]+1]][1]=cnt;
		yjy[a[i]+1]=cnt^1;
	}
	for (int i=1;i<=n;i++){
		++cnt;
		if (f[cnt]=yjy[i])
			s[yjy[i]][1]=cnt;
	}
	int Q;
	scanf("%d",&Q);
	while (Q--){
		int T,x;
		scanf("%d%d",&T,&x);
		if (T==1){
			int p=(m-x+1)*2,q=p+1;
			splay(p);splay(q);
			if (s[p][1]) f[s[p][1]]=q;
			if (s[q][1]) f[s[q][1]]=p;
			swap(s[p][1],s[q][1]);
		}
		else {
			x+=2*m+1;
			splay(x);
			int ret=x;
			for (;s[ret][0];ret=s[ret][0]);
			printf("%d\n",ret<=2*m+1?a[m-ret/2+1]+(ret&1):x-2*m-1);
		}
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章