Longest Subarray(HDU6602+线段树)
Posted shuaihui520
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
以上是关于Longest Subarray(HDU6602+线段树)的主要内容,如果未能解决你的问题,请参考以下文章
HDU6602 Longest Subarray(思维+线段树区间修改维护最值)
2019杭电多校第二场hdu6602 Longest Subarray(线段树)
LeetCode 978. Longest Turbulent Subarray