Longest Subarray(HDU6602+线段树)
题意
要你找一个最长的区间使得区间内每一个数出现次数都大于等于K。
题解-》https://blog.csdn.net/Ratina/article/details/97503663
#include<bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn=1e5+50; int N,C,K,a[maxn]; int mx[maxn<<2],laz[maxn<<2]; void pushdown(int rt){ if(laz[rt]==0) return ; mx[rt<<1]+=laz[rt]; mx[rt<<1|1]+=laz[rt]; laz[rt<<1]+=laz[rt]; laz[rt<<1|1]+=laz[rt]; laz[rt]=0; } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R) { laz[rt]+=c; mx[rt]+=c; return ; } pushdown(rt); int m=(l+r)>>1; if(L<=m) update(L,R,c,lson); if(R>m) update(L,R,c,rson); mx[rt]=max(mx[rt<<1],mx[rt<<1|1]); } int query(int rt, int l, int r){ if(l==r) return l; pushdown(rt); int mid=(l+r)>>1; if(mx[rt<<1]==C) return query(rt<<1,l,mid); else if(mx[rt<<1|1]==C) return query(rt<<1|1,mid+1,r); else return -1; } int main(){ while(~scanf("%d%d%d",&N,&C,&K)){ vector<int>pos[maxn]; for(int i=1;i<=C;i++) pos[i].push_back(0); for(int i=1;i<=N;i++) { scanf("%d",&a[i]); pos[a[i]].push_back(i); } if(K==1){ printf("%d\n",N); continue; } memset(mx,0,sizeof(mx)); memset(laz,0,sizeof(laz)); int ans=0,cur[maxn]={0}; for(int i=1;i<=N;i++){ int x=a[i]; int p=++cur[x]; update(i,i,C-1,1,N,1); if(pos[x][p-1]+1<=pos[x][p]-1) update(pos[x][p-1]+1,pos[x][p]-1,-1,1,N,1); if(p>=K) update(pos[x][p-K]+1,pos[x][p-K+1],1,1,N,1); int temp=query(1,1,N); if(temp!=-1) ans=max(ans,i-temp+1); } printf("%d\n",ans); } }