标签:codeforces 思维题 扫描法 等价转换
1.题目描述:点击打开链接
2.解题思路:本题是一道很好的思维题。看好多人用单调栈解决的。这里介绍另一种解决方法:首先,根据题意描述,我们知道连续序列的最小值是关键,如果任意给出一个连续序列,找它的最小值,反而不太方便;但是换个角度,如果知道最小值,求以它为最小值的最大的连续序列!这就简单的多了。即找出这个元素向左可以延伸多远,向右能延伸多远,然后就能求出最大连续序列的长度了。
现在的问题是,如何快速找到每个元素向右能延伸的最远距离,向左能够延伸的最远距离?这里我们尝试利用扫描法解决。用L[i]表示第i个元素向左能够延伸的最远的下标,R[i]表示向右的最远下标。初始化的时候L[i]=R[i]=i。接下来我们利用不等式关系来寻找最远下标。
假设枚举到了第i个元素val[i],那么它左边的元素就是val[L[i]-1](因为初始化的时候L[i]=i,等价于val[i-1]),如果有val[L[i]-1]>=val[i],那么L[i]就是元素val[L[i]-1]的最左边的下标L[L[i]-1],即L[i]=L[L[i]-1],接下来继续判断是否有val[L[i]-1]>=val[i]成立,直到不满足这个关系式为止。这样我们就找到了L[i]。同理也可找到R[i],那么val[i]所在的最长的连续子序列长度就是R[i]-L[i]+1。
最后,我们将(len,val)看做一个二元组,对len排序,那么对于每一个len,只需要更新所有的d<=len的答案即可(d表示长度)。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> P; typedef pair<long long,long long> PL; #define me(s) memset(s,0,sizeof(s)) #define For(i,n) for(int i=0;i<(n);i++) #define pb push_back #define sz size #define clr clear #define N 200000+6 struct Node { int len,num; }a[N]; int T,t,n,m; int L[N],R[N]; int val[N],ans[N]; bool cmp(Node a,Node b) { return a.num>b.num; } int main() { // freopen("t.txt","r",stdin); int len; while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) { scanf("%d",&val[i]); L[i]=R[i]=i; } for(int i=1;i<=n;i++) while(val[L[i]-1]>=val[i])//更新最左边的下标 L[i]=L[L[i]-1]; for(int i=n;i>=1;i--) while(val[R[i]+1]>=val[i])//更新最右边的下标 R[i]=R[R[i]+1]; for(int i=1;i<=n;i++) { a[i].len=R[i]-L[i]+1;//计算出最长连续子串的长度 a[i].num=val[i]; } sort(a+1,a+n+1,cmp);//对长度排序 ans[0]=1e9+7;//a[0]要置为一个比所有元素都大的值,这样保证后面的while循环一定会停止 for(int i=1;i<=n;i++) { len=a[i].len; while(ans[len]<a[i].num)//更新所有长度不超过len的答案 { ans[len]=a[i].num; len--; } } for(int i=1;i<=n;i++) printf("%d%c",ans[i],i==n?'\n':' '); } return 0; }
标签:codeforces 思维题 扫描法 等价转换
原文地址:http://blog.csdn.net/u014800748/article/details/46121267