Slip through the net

Title Description

Given an n-$ $ $ A $ sequence number, there are times $ Q $ query, asking each time interval $ [l, r] $ all subranges MEX $ and $.

data range

$ 1 \ n, Q \ the $ 10 ^ 6; $ 0 \ the a_i \ 10 ^ 9 $

answer

Consider the $ [l, r] $ answer is split into a starting point in the $ [1, r] $, in the end the answer $ [l, r] $ subtracted from the starting point at $ [1, l-1] $ answer.

Consider off-line, consider promoting l pointer, the segment tree endpoint $ r $ maintenance $ [l, r] $ of $ mex $ and historical information. Consider the contribution of $ l $ to $ l + 1 $ of time, draw a map will find that it will change for some interval $ a_l $.

Now consider the end of the $ r $, how to maintain the starting point of the total answer $ [1, l] $, taking in $ mex $ each time change, the original contribution of $ mex $ is $ (l-last) \ times mex $, the equation apart, that is, $ l \ times mex-last \ times mex $, and thus can maintain the value and subtracting the sum of history now $ mex \ times last $ of $ mex $ tree line with previous inquiries when to go with $ l $ query.

Efficiency: $ O (nlogn) $

Code

#include <bits/stdc++.h>
#define LL long long
#define _(d) while(d(isdigit(c=getchar())))
using namespace std;
int Rd(){
    char c;_(!);int x=c^48;
    _()x=(x<<3)+(x<<1)+(c^48);return x;
}
const int N=1e6+5,M=N<<2;
int Ty,n,nx[N],lst[N],a[N],q,b[N],ax[M],g[M][2];
LL ans[N],s[M][2],tg[M][2];
bool vis[N];
struct O{
    int l,r,i,x;
}p[N*2];
bool cmp(O A,O B){return A.x<B.x;}
#define Ls k<<1
#define Rs k<<1|1
#define mid ((l+r)>>1)
void down(int k,int l,int r){
    if (!tg[k][0] && !tg[k][1]) return;
    s[k][0]+=tg[k][0]*(r-l+1);
    s[k][1]+=tg[k][1]*(r-l+1);
    if (l<r){
        tg[Ls][0]+=tg[k][0];tg[Ls][1]+=tg[k][1];
        tg[Rs][0]+=tg[k][0];tg[Rs][1]+=tg[k][1];
    }
    tg[k][0]=tg[k][1]=0;
}
void up(int k,int l,int r){
    s[k][0]=s[Ls][0]+(mid-l+1)*tg[Ls][0]+s[Rs][0]+(r-mid)*tg[Rs][0];
    s[k][1]=s[Ls][1]+(mid-l+1)*tg[Ls][1]+s[Rs][1]+(r-mid)*tg[Rs][1];
    g[k][0]=max(g[Ls][0],g[Rs][0]);
    g[k][1]=(g[Ls][1] || g[Rs][1] || g[Ls][0]!=g[Rs][0]);
}
void build(int k,int l,int r){
    if (l==r){g[k][0]=s[k][0]=b[l];return;}
    build(Ls,l,mid);build(Rs,mid+1,r);up(k,l,r);
}
LL qry(int k,int l,int r,int L,int R,int i){
    down(k,l,r);
    if (L<=l && r<=R) return s[k][0]*i+s[k][1];
    if (mid>=R) return qry(Ls,l,mid,L,R,i);
    if (mid<L) return qry(Rs,mid+1,r,L,R,i);
    return qry(Ls,l,mid,L,R,i)+qry(Rs,mid+1,r,L,R,i);
}
void upd(int k,int l,int r,int L,int R,int i,int v){
    if (l<r && !g[k][1]) g[Ls][0]=g[Rs][0]=g[k][0];
    down(k,l,r);
    if (L<=l && r<=R && !g[k][1]){
        tg[k][0]+=v-g[k][0];
        tg[k][1]-=1ll*(v-g[k][0])*(i-1);
        g[k][0]=v; down(k,l,r); return;
    }
    if (mid>=L && g[Ls][0]>v) upd(Ls,l,mid,L,R,i,v);
    if (mid<R && g[Rs][0]>v) upd(Rs,mid+1,r,L,R,i,v);
    up(k,l,r);
}
int main(){
    Ty=Rd();n=Rd();
    for (int i=1;i<=n;i++){
        a[i]=min(Rd(),n);
        nx[lst[a[i]]]=i,lst[a[i]]=i;
    }
    q=Rd();
    for (int j=0,l,r,i=1;i<=q;i++){
        l=Rd(),r=Rd();
        p[++j]=(O){l,r,i,l-1};
        p[++j]=(O){l,r,i,r};
    }
    sort(p+1,p+q+q+1,cmp);
    for (int i=1;i<=n;i++){
        vis[a[i]]=1;b[i]=b[i-1];
        while(vis[b[i]]) b[i]++;
        if (!nx[i]) nx[i]=n+1;
    }
    build(1,1,n); int j=1; while(!p[j].x) j++;
    for (int i=1;i<=n;i++){
        while(p[j].x==i)
            ans[p[j].i]+=(p[j].x<p[j].l?-1:1)*
            qry(1,1,n,p[j].l,p[j].r,i),j++;
        upd(1,1,n,i,nx[i]-1,i+1,a[i]);
    }
    for (int i=1;i<=q;i++)
        printf("%lld\n",ans[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/xjqxjq/p/12047243.html