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; }