两个set

http://112.74.32.32/problem/1004

水涛插板子

Description

 

水涛有n个珠子,从左到右排成一条直线,并且这n个珠子各自的价值。

有一天,水涛想指定一个数x,把所有珠子的价值大于等于x的都去掉,且在去掉的位置插入一个板子,并且水涛一开始就将0和n+1的位置插入了板子。

此时水涛会从1位置出发收取剩下的珠子直到遇到一个板子时停止,并记录收取次数cnt+1,且记录此次收取了w个珠子,然后水涛就跳过这个板子继续收取珠子.一直按照这样的收取方法直到到达n+1位置.

如果水涛在一次收取中得到了0个珠子,那么他将不会记录它。

如果水涛在一次记录收取珠子的个数时发现与之前的某一次记录收取珠子数不同,那么说明x这个数是不好的。

现在水涛想知道当x取多少时,x是好的且使得记录收取次数最多,如果有多个x满足条件输出最小的x。记录收取次数cnt初始化为0.

Input

 

输入有多组样例.

第一行输入一个整数n(1<=n<=1e5)

第二行输入n个整数,第i个数表示第i个珠子的值a[i].(1<=a[i]<=1e9),保证所有a[i]都不同

Output

 

输出一行数表示x的最佳取值

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
#define mem(a,x) memset(a,x,sizeof(a))
#define s1(x) scanf("%d",&x)
#define s2(x,y) scanf("%d%d",&x,&y)
#define s3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define s4(x,y,z,k) scanf("%d%d%d%d",&x,&y,&z,&k)
#define ff(a,n) for(int i = 0 ; i < n; i++) scanf("%d",a+i)
#define ls 2*rt
#define rs 2*rt+1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define ll long long
using namespace std;
typedef pair<int,int> pii;
//inline ll ask(int x){ll res=0;while(x)res+=c[x],x-=x&(-x);return res;}
//inline void add(int x,int d){while(x<=n)c[x]+=d,x+=x&(-x);}
//int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b);}
const ll inf = 0x3f3f3f3f;
const int mx = 1e5+10;
multiset<int>ms;
set<int>s;
multiset<int> :: iterator m1,m2;
set<int> :: iterator it2;
struct no{
	int x,po;
}p[mx];
int n;
bool cmp(no &a, no &b){
	return a.x<b.x;
}
int main(){
	//	freopen("F:\\in.txt","r",stdin);
	//int T=10;	scanf("%d",&T);
	while(s1(n) != EOF){
		s.clear();
		ms.clear();
		for(int i = 1; i <= n; i++){
			scanf("%d",&p[i].x);
			p[i].po = i;
		}
		if(n==1){
			cout<<p[1].x+1<<endl;
			continue;
		} 
		sort(p+1,p+1+n,cmp);
		s.insert(0);
		s.insert(n+1);
		ms.insert(n);
		int ans,cnt=-1;
		int len,a,b;
		for(int i = n; i > 1; i--){
			s.insert(p[i].po);
			it2 = s.lower_bound(p[i].po);
			it2++; a=*it2;
			it2--;it2--; b = *it2;
			len = a-b-1;
			m1=ms.lower_bound(len);
			ms.erase(m1);
			if(a-p[i].po > 1){
				ms.insert(a-p[i].po-1);
			}
			if(p[i].po -b > 1){
			//	cout<<"charu"<<p[i].po-b-1<<endl;
				ms.insert(p[i].po-b-1);
			}
			
			m1=ms.begin(); m2 = ms.end(); m2--;
			//cout<<*m1<<"=="<<*m2<<"size="<<ms.size()<<endl;
			int h1 = *m1,h2=*m2,h3=ms.size();
			//cout<<cnt<<"**"<<endl;
			if( h1==h2 && h3>=cnt){   //不能写size()>= cnt 
				//cout<<"jin"<<endl; 
				ans = p[i-1].x+1;
				cnt = ms.size();
			}
			
		}
		if(cnt == -1){
			cout<<p[n].x+1<<endl;
		
		}
		else
			cout<<ans<<endl;
	}
	
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blaze Jack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值