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

题意:给你一个序列,让你找一个k,倘若把大于等于k的元素都标记为不可用,那么剩下的所有元素形成的段的长度相同,并且使得段的数量尽量大。如果有多解,输出k尽量小的。

把元素从大到小排序插回原位置,用一个set维护前驱后继,相当于删除一个原有的段,然后将这个段切成两半,产生两个新的段。维护这次操作后所有段的长度以及各种长度的出现次数(用multiset),一旦合法,就尝试更新答案。

#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;
}
posted @ 2018-05-18 11:49  AutSky_JadeK  阅读(273)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト