题意:
1e5的数组,c(1e5)种数字求最长的子串,使得其中每个出现的数字出现的次数为0次或者大于k次
思路:
枚举右端点i,维护当前右端点时,每个左端点的可行元素数量,当且仅当可行元素为c时更新答案
每次用最左边的可行的左端点与当前右端点更新答案
对于每个元素,如果它从i往左第1次出现的元素为pos1,第k次出现的为pos2
那么该元素的可行区域为[1,pos2]与[pos1+1,i]
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<stack> #include<queue> #include<deque> #include<set> #include<vector> #include<map> #define fst first #define sc second #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lc root<<1 #define rc root<<1|1 using namespace std; typedef double db; typedef long double ldb; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PI; typedef pair<ll,ll> PLL; const db eps = 1e-6; const int mod = 1e9+7; const int maxn = 2e5+100; const int maxm = 4e6+100; const int inf = 0x3f3f3f3f; const db pi = acos(-1.0); int n,c,k; int a[maxn]; vector<int>v[maxn]; int mx[maxn<<2]; int addv[maxn<<2]; void build(int l, int r, int root){ int mid = (l+r)>>1; if(l==r){mx[root]=c;return;} build(lson); build(rson); mx[root]=max(mx[lc],mx[rc]); addv[root]=0; return; } void pushdown(int l, int r, int root){ if(addv[root]){ addv[lc]+=addv[root]; addv[rc]+=addv[root]; mx[lc]+=addv[root]; mx[rc]+=addv[root]; addv[root]=0; } return; } void update(int x, int y, int val, int l, int r, int root){ int mid = (l+r)>>1; if(x<=l&&r<=y){ addv[root]+=val; mx[root]+=val; return; } pushdown(l,r,root); if(x<=mid)update(x,y,val,lson); if(y>mid)update(x,y,val,rson); mx[root]=max(mx[rc],mx[lc]); return; } int ask(int l, int r, int root){ int mid = (l+r)>>1; if(l==r){ if(mx[root]==c)return l; else return inf; } pushdown(l,r,root); if(mx[lc]==c)return ask(lson); else if(mx[rc]==c)return ask(rson); return inf; } int main(){ while(~scanf("%d %d %d", &n, &c, &k)){ for(int i = 1; i <= n; i++){v[i].clear();v[i].pb(0);} for(int i = 1; i <= n; i++){ scanf("%d", &a[i]); } build(1,n,1); int ans = 0; for(int i = 1; i <= n; i++){ if((int)v[a[i]].size()>k){ int l = v[a[i]][v[a[i]].size()-k]; int r = v[a[i]].back(); update(l+1,r,1,1,n,1); v[a[i]].pb(i); l=v[a[i]][v[a[i]].size()-k]; r=v[a[i]].back(); update(l+1,r,-1,1,n,1); } else{ update(v[a[i]].back()+1,i,-1,1,n,1); v[a[i]].pb(i); if((int)v[a[i]].size()>k){ int l = v[a[i]][v[a[i]].size()-k]; update(1,l,1,1,n,1); } } int L = ask(1,n,1); ans=max(ans,max(0,i-L+1)); } printf("%d\n",ans); } return 0; } /* 7 5 2 3 1 5 2 5 2 3 */