首页 > 技术文章 > codeforces #305 B Mike and Feet

joyouth 2016-04-04 21:09 原文

跟之前做过的51Nod的移数博弈是一样的QAQ

我们考虑每个数的贡献

定义其左边第一个比他小的数的位置为L

定义其右边第一个比他小的数的位置为R

这个可以用排序+链表 或者 单调队列 搞定

那么对于区间长度1->(R-L-1),该数都可以作为最小值出现

我们在R-L-1上打上标记,最后从后往前来更新答案即可

至此问题得解

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
using namespace std;

const int maxn=200010;
int n;
struct Num{
	int v,p;
}A[maxn],B[maxn];

int nxt[maxn],pre[maxn];
int mx[maxn],ans[maxn];

bool cmp(const Num &A,const Num &B){return A.v>B.v;}
void del(int now){
	nxt[pre[now]]=nxt[now];
	pre[nxt[now]]=pre[now];
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&A[i].v);A[i].p=i;
		B[i]=A[i];
	}
	sort(B+1,B+n+1,cmp);
	for(int i=1;i<=n;++i)nxt[i]=i+1,pre[i]=i-1;
	pre[0]=0;nxt[n+1]=n+1;
	for(int i=1;i<=n;++i){
		int now=B[i].p;
		int L=pre[now],R=nxt[now];
		mx[R-L-1]=max(mx[R-L-1],B[i].v);
		del(now);
	}
	for(int i=n;i>=1;--i)ans[i]=max(ans[i+1],mx[i]);
	for(int i=1;i<=n;++i)printf("%d ",ans[i]);
	return 0;
}

  

推荐阅读