題意:給你一個序列,讓你找一個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; }