非常好的线段树题。。。。此题必定会火。。。。。
Mex
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 955 Accepted Submission(s): 320
Problem Description
Mex is a function on a set of integers, which is universally used for impartial game theorem. For a non-negative integer set S, mex(S) is defined as the least non-negative integer which is not appeared in S. Now our problem is about mex function on a sequence.
Consider a sequence of non-negative integers {ai}, we define mex(L,R) as the least non-negative integer which is not appeared in the continuous subsequence from aL to aR, inclusive. Now we want to calculate the sum of mex(L,R) for all 1 <= L <= R <= n.
Consider a sequence of non-negative integers {ai}, we define mex(L,R) as the least non-negative integer which is not appeared in the continuous subsequence from aL to aR, inclusive. Now we want to calculate the sum of mex(L,R) for all 1 <= L <= R <= n.
Input
The input contains at most 20 test cases.
For each test case, the first line contains one integer n, denoting the length of sequence.
The next line contains n non-integers separated by space, denoting the sequence.
(1 <= n <= 200000, 0 <= ai <= 10^9)
The input ends with n = 0.
For each test case, the first line contains one integer n, denoting the length of sequence.
The next line contains n non-integers separated by space, denoting the sequence.
(1 <= n <= 200000, 0 <= ai <= 10^9)
The input ends with n = 0.
Output
For each test case, output one line containing a integer denoting the answer.
Sample Input
3
0 1 3
5
1 0 2 0 10
0 1 3
5
1 0 2 0 10
Sample Output
5
24
24
Hint
For the first test case:mex(1,1)=1, mex(1,2)=2, mex(1,3)=2, mex(2,2)=0, mex(2,3)=0,mex(3,3)=0. 1 + 2 + 2 + 0 +0 +0 = 5.Source
Recommend
liuyiding

#include <iostream> #include <cstdio> #include <cstring> #include <map> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int maxn=200005; typedef long long int LL; int a[maxn],mex[maxn],next[maxn],mx[maxn<<2],sig[maxn<<2],cnt; LL sum[maxn<<2]; bool vis[maxn]; void pushUP(int rt) { mx[rt]=max(mx[rt<<1],mx[rt<<1|1]); sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void pushDOWN(int rt,int len) { if(~sig[rt]) { sig[rt<<1]=sig[rt<<1|1]=sig[rt]; mx[rt<<1]=mx[rt<<1|1]=sig[rt]; sum[rt<<1]=sig[rt]*(len-len>>1); sum[rt<<1|1]=sig[rt]*(len>>1); sig[rt]=-1; } } void build(int l,int r,int rt) { if(l==r) { mx[rt]=mex[cnt]; sum[rt]=mex[cnt++]; return ; } int m=(r+l)>>1; build(lson); build(rson); pushUP(rt); } LL query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) { return sum[rt]; } pushDOWN(rt,r-l+1); int m=(l+r)>>1; LL ret=0; if(L<=m) ret+=query(L,R,lson); if(R>m) ret+=query(L,R,rson); return ret; } int getID(int L,int R,int v,int l,int r,int rt) { if(l==r) return l; pushDOWN(rt,r-l+1); int m=(r+l)>>1; if(L<=m&&mx[rt<<1]>v) return getID(L,R,v,lson); else if(R>m&&mx[rt<<1|1]>v) return getID(L,R,v,rson); return R+1; } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R) { sig[rt]=c; mx[rt]=c; sum[rt]=c*(r-l+1); return ; } pushDOWN(rt,r-l+1); int m=(r+l)>>1; if(L<=m) update(L,R,c,lson); if(R>m) update(L,R,c,rson); pushUP(rt); } int main() { int n; while(scanf("%d",&n)!=EOF&&n) { for(int i=1;i<=n;i++) scanf("%d",a+i); memset(vis,false,sizeof(vis)); mex[1]=0; if(a[1]<n) vis[a[1]]=true; while(vis[mex[1]]) mex[1]++; for(int i=2;i<=n;i++) { if(a mex while(vis[mex } map<int,int> mII; for(int i=n;i>=1;i--) { if(mII.find(a else next mII[a } cnt=1;LL ans=0; memset(mx,0,sizeof(mx)); memset(sum,0,sizeof(sum)); memset(sig,-1,sizeof(sig)); build(1,n,1); for(int i=1;i<=n;i++) { ans+=query(i,n,1,n,1); int st=getID(i+1,next int ed=next if(st<=ed) update(st,ed,a } printf("%I64d ",ans); } return 0; } |