【set】【multiset】Codeforces Round #484 (Div. 2) D. Shark

題意:給你一個序列,讓你找一個k,假若把大於等於k的元素都標記爲不可用,那麼剩下的全部元素造成的段的長度相同,而且使得段的數量儘可能大。若是有多解,輸出k儘可能小的。spa

把元素從大到小排序插回原位置,用一個set維護前驅後繼,至關於刪除一個原有的段,而後將這個段切成兩半,產生兩個新的段。維護此次操做後全部段的長度以及各類長度的出現次數(用multiset),一旦合法,就嘗試更新答案。blog

#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
typedef pair<int,int> Point;
set<int>S;
multiset<int>S2;
int n;
Point a[100005];
int all,ans,maxnum;
int main(){
	scanf("%d",&n);
	int x;
	S2.insert(n);
	maxnum=1;
	for(int i=1;i<=n;++i){
		scanf("%d",&x);
		a[i].first=x;
		a[i].second=i;
	}
	sort(a+1,a+n+1);
	ans=a[n].first+1;
	S.insert(0);
	S.insert(n+1);
	for(int i=n;i>=1;--i){
		S.insert(a[i].second);
		int y=*S.upper_bound(a[i].second);
		set<int>::iterator it=S.lower_bound(a[i].second); --it;
		int x=*it;
		S2.erase(S2.find(y-x-1));
		if(y-a[i].second>1){
			S2.insert(y-a[i].second-1);
		}
		if(a[i].second-x>1){
			S2.insert(a[i].second-x-1);
		}
		if(!S2.empty()){
			multiset<int>::iterator jt=S2.end(); --jt;
			if((*S2.begin())==(*jt)){
				if(S2.size()>maxnum || (S2.size()==maxnum && a[i-1].first+1<ans)){
					maxnum=S2.size();
					ans=a[i-1].first+1;
				}
			}
		}
	}
	printf("%d\n",ans);
	return 0;
}
相關文章
相關標籤/搜索