Multi correction 2 Longest Subarray line segment tree

Keywords: PHP

Given n C k and sequence ai (1-n), find the longest interval length, so that the number of elements in the interval is 0 or > = k, and all numbers are in the range of 1-C.

 

Explanation:

If the right endpoint is fixed, the feasible left endpoint subscript is two consecutive intervals for each element.
For each element, add one feasible left endpoint interval to the line segment tree.
When the right endpoint moves to the right, maintain the feasible left endpoint of C elements.
When querying, you only need to query the lowest subscript in the segment tree with a value of C.

 

It's very clear to draw a picture. A very good line tree problem.

Pay attention to the way of maintaining the lowest subscript

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define lson l,m,pos<<1
#define rson m+1,r,pos<<1|1
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=1e5+5;
int t[N<<2],col[N<<2],x[N<<2];
int C,k,n,m;
vector<int>v[N];
void up(int pos)
{
    t[pos]=max(t[pos<<1],t[pos<<1|1]);
    x[pos]=(t[pos]==t[pos<<1])?x[pos<<1]:x[pos<<1|1];
}
void down(int pos)
{
    if(col[pos])
    {
        t[pos<<1]+=col[pos];
        t[pos<<1|1]+=col[pos];
        col[pos<<1]+=col[pos];
        col[pos<<1|1]+=col[pos];
        col[pos]=0;
    }
}
void build(int l,int r,int pos)
{
    x[pos]=l;col[pos]=0;
    if(l==r){t[pos]=0;return ; }
    int m=(l+r)>>1;build(lson);build(rson);up(pos);
}
void upsum(int L,int R,int v,int l,int r,int pos)
{
    if(L>R)return ;
    if(L<=l&&r<=R){ col[pos]+=v;t[pos]+=v;return ;  }
    int m=(l+r)>>1;down(pos);
    if(L<=m)upsum(L,R,v,lson);
    if(R>m)upsum(L,R,v,rson);
    up(pos);
}
int qsum(int L,int R,int l,int r,int pos)
{
    if(L<=l&&r<=R)
    {
        return t[pos]==C?x[pos]:0;
    }
    int m=(l+r)>>1;down(pos);
    if(L<=m)//Be sure to pay attention to the details here
    {
        int t=qsum(L,R,lson);
        if(t)return t;
    }
    if(R>m)return qsum(L,R,rson);
    return 0;
}
int c;
int main()
{
    while(cin>>n>>C>>k)
    {
        rep(i,1,C+1)v[i].clear(),v[i].pb(0);
        build(1,n,1);
        int ans=0;
        rep(i,1,n)
        {
            RI(c);
            upsum(i,i,C-1,1,n,1);

            upsum(v[c].back()+1,i-1,-1,1,n,1);
            v[c].pb(i);
            int p=(v[c].size()-k-1);
            if(p>=0)
            upsum(v[c][p]+1,v[c][p+1],1,1,n,1);
            int j=qsum(1,n,1,n,1);
            if(!j)continue;
            ans=max(ans,i-j+1);
        }
        cout<<ans<<endl;
    }
    return 0;
}

Posted by m@tt on Wed, 16 Oct 2019 12:14:56 -0700