Nice Sequence
Time Limit: 12000/6000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others)
Problem Description
Let us consider the sequence a1, a2,..., an of non-negative integer numbers. Denote as ci,j the number of occurrences of the number i among a1,a2,..., aj. We call the sequence k-nice if for all i1<i2 and for all j the following condition is satisfied: ci1,j ≥ ci2,j −k.
Given the sequence a1,a2,..., an and the number k, find its longest prefix that is k-nice.
Input
The first line of the input file contains n and k (1 ≤ n ≤ 200 000, 0 ≤ k ≤ 200 000). The second line contains n integer numbers ranging from 0 to n.
Output
Output the greatest l such that the sequence a1, a2,..., al is
k-nice.
Sample Input
10 1 0 1 1 0 2 2 1 2 2 3 2 0 1 0
Sample Output
8 0
Source
Andrew Stankevich Contest 23
Manager
题解及代码:
比赛的时候是队友写的这道题,由于查询的时候要进行优化,所以给他加了一个线段树维护区间最小值就AC了。
今天看了一下这道题,感觉也不难。它的定义有些难懂啊。事实上就是当我们从左向右输入到一个元素x时,要保证其左側元素中1-(x-1)出现的次数大于等于 x的出现次数-k,找出这种最长的前缀。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <set> #include <map> #include <queue> #include <string> #define maxn 200010 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; int a[200005]; struct segment { int l,r; int value; } son[maxn<<2]; void PushUp(int rt) { son[rt].value=min(son[rt<<1].value,son[rt<<1|1].value); } void Build(int l,int r,int rt) { son[rt].l=l; son[rt].r=r; if(l==r) { son[rt].value=0; return; } int m=(l+r)/2; Build(lson); Build(rson); PushUp(rt); } void Update(int p,int rt) { if(son[rt].l==son[rt].r) { son[rt].value++; return; } int m=(son[rt].l+son[rt].r)/2; if(p<=m) Update(p,rt<<1); else Update(p,rt<<1|1); PushUp(rt); } int Query(int l,int r,int rt) { if(son[rt].l==l&&son[rt].r==r) { return son[rt].value; } int ret=0; int m=(son[rt].l+son[rt].r)/2; if(r<=m) ret=Query(l,r,rt<<1); else if(l>m) ret=Query(l,r,rt<<1|1); else { ret=Query(lson); ret=min(ret,Query(rson)); } return ret; } int main() { int n,k,x,ans=0; bool flag=false; scanf("%d%d",&n,&k); Build(1,n+1,1); for(int i=1;i<=n;i++) { scanf("%d",&x); if(!flag) { x++; a[x]++; Update(x,1); if(Query(1,x,1)<a[x]-k) flag=true; if(!flag) ans=i; } } printf("%d ",ans); return 0; }