题目
For some array c, let’s denote a greedy subsequence as a sequence of indices p1, p2, …, pl such that 1≤p1<p2<⋯<pl≤|c|, and for each i∈[1,l−1], pi+1 is the minimum number such that pi+1>pi and c[pi+1]>c[pi].
You are given an array a1,a2,…,an. For each its subsegment of length k, calculate the length of its longest greedy subsequence.
Input
The first line contains two integers n and k (1≤k≤n≤106) — the length of array a and the length of subsegments.
The second line contains n integers a1,a2,…,an (1≤ai≤n) — array a.
Output
Print n−k+1 integers — the maximum lengths of greedy subsequences of each subsegment having length k. The first number should correspond to subsegment a[1…k], the second — to subsegment a[2…k+1], and so on.
Examples
inputCopy
6 4
1 5 2 5 3 6
outputCopy
2 2 3
inputCopy
7 6
4 5 2 5 3 6 6
outputCopy
3 3
Note
In the first example:
[1,5,2,5] — the longest greedy subsequences are 1,2 ([c1,c2]=[1,5]) or 3,4 ([c3,c4]=[2,5]).
[5,2,5,3] — the sequence is 2,3 ([c2,c3]=[2,5]).
[2,5,3,6] — the sequence is 1,2,4 ([c1,c2,c4]=[2,5,6]).
In the second example:
[4,5,2,5,3,6] — the longest greedy subsequences are 1,2,6 ([c1,c2,c6]=[4,5,6]) or 3,4,6 ([c3,c4,c6]=[2,5,6]).
[5,2,5,3,6,6] — the subsequence is 2,3,5 ([c2,c3,c5]=[2,5,6]).
题意
给定一个序列a,定义它的最长贪心严格上升子序列为b满足若ai在b中则ai之后第一个比它大的也在b中。给出一个数k,求出所有长度为k的子区间的最长贪心严格上升子序列。
思路
感谢beginend大爷的指导。
我们可以把它看成一棵树(根据next连边)。
现在要求一些关键点最多能往上跳多少步。
如果只有一个询问,那么随便做。但现在有多个询问,那么要维护一个可以插入删除的树。
不难发现,如果加入一个点,那么它的子树一定已经加入过,这只需一个区间加就行。如果删除一个数,那么它的子树早就被删了,秩序把那个点赋值为-INF即可
用线段树轻松维护
代码
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 1000100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int a[MAX],n,K,St[MAX],top,L[MAX];
#define lson (now<<1)
#define rson (now<<1|1)
int t[MAX<<2],tag[MAX<<2];
void puttag(int now,int w){t[now]+=w;tag[now]+=w;}
void pushdown(int now)
{
if(!tag[now])return;
puttag(lson,tag[now]);puttag(rson,tag[now]);
tag[now]=0;
}
void Modify(int now,int l,int r,int L,int R,int w)
{
if(L<=l&&r<=R){puttag(now,w);return;}
int mid=(l+r)>>1;pushdown(now);
if(L<=mid)Modify(lson,l,mid,L,R,w);
if(R>mid)Modify(rson,mid+1,r,L,R,w);
t[now]=max(t[lson],t[rson]);
}
int Query(int now,int l,int r,int L,int R)
{
if(L<=l&&r<=R)return t[now];
int mid=(l+r)>>1,ret=0;pushdown(now);
if(L<=mid)ret=max(ret,Query(lson,l,mid,L,R));
if(R>mid)ret=max(ret,Query(rson,mid+1,r,L,R));
return ret;
}
int main()
{
n=read();K=read();
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=n;++i)
{
while(top&&a[St[top]]<a[i])--top;
L[i]=St[top];St[++top]=i;
}
for(int i=1;i<=n;++i)
{
Modify(1,1,n,L[i]+1,i,1);
if(i>=K)printf("%d ",Query(1,1,n,i-K+1,i));
}
return 0;
}