[ACM]【map/分治】廈大月賽 環鴿的CHONG

環鴿的CHONG

傳送門
題意:
輸入一個數列,如果該數列任意連續子序列滿足存在一個數是唯一的(是”好序列“),輸出chong,否則輸出fuchong。
圖

思路:

分治思想。
如果(1,n)滿足要求(是好序列),且唯一數是a[x]。那麼,包括a[x]的所有序列都滿足要求;只需要考慮不包括的滿不滿足。即考慮(1,x-1)和(x+1,n)。如此分治下去。
如何快速判斷有無唯一數呢?
這裏有一個技巧:對於每一個位置上的數,預處理記錄在他左邊離他最近的數值相同的數的位置,和在他右邊離他最近的數值相同的數的位置。
如何記錄呢,通過map。

代碼:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
int a[maxn];
map<int,int>mp;
int l[maxn],r[maxn];
bool dfs(int low,int high){
	if(high<=low) return 1;
	for(int i=low;i<=high;i++){
		if(l[i]<low&&r[i]>high)
			return dfs(low,i-1)&&dfs(i+1,high);
	}
	return 0;
}
int main(){
	int n,flag=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		if(!mp[a[i]]) l[i]=0;
		else l[i]=mp[a[i]];
		mp[a[i]]=i; 
		//記錄左邊最近相等數的位置
		if(a[i]==a[i-1]) flag=1;
		//如果有兩個連着的數一樣,
		//那(1,n)必定不是好序列。
	}
	if(flag){
		printf("fuchong\n");
		return 0;
	}
	mp.clear();
	for(int i=n;i;i--){
		if(!mp[a[i]]) r[i]=n+1;
		else r[i]=mp[a[i]];
		mp[a[i]]=i;
		//記錄右邊最近相等數的位置
	}
	if(dfs(1,n)) printf("chong\n");
	else printf("fuchong\n");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章