您的位置:首页 > 其它

HDU 4747 Mex (线段树)

2014-11-19 17:08 323 查看
参考1  

参考2




Mex

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)

Total Submission(s): 2011    Accepted Submission(s): 662


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.

 

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.

 

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 1
0

 

Sample Output

5
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

2013 ACM/ICPC Asia Regional Hangzhou Online

 

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>

using namespace std;
#define ll long long
#define prt(k) cerr<<#k" = "<<k<<endl

const int N = 200014;
const int Lim = 200000;
#define lson l,m,o*2
#define rson m+1,r,o*2+1
ll mex1
;
int a
;
int next
;
int vis
;
int n;
void getMex1()
{
memset(vis, 0, sizeof vis);
int ret = 0;
for(int i=1;i<=n;i++)
{
vis[a[i]]=true;
for(; vis[ret]; ret++) ;
mex1[i] = ret;
}
}
void getNext()
{
for(int i=0;i<N;i++) vis[i]=n+1;
for(int i=n;i>=1;i--)
{
next[i] = vis[a[i]];
vis[a[i]] = i;
}
}
ll tree[N<<2], sumo[N<<2];
#define ls o*2
#define rs o*2+1
ll lazy[N<<2];
void pushup(int l, int r,int o)
{
tree[o]=max(tree[ls], tree[rs]);
sumo[o]=sumo[ls] + sumo[rs];
}
void build(int l,int r, int o)
{
lazy[o] = -1;
if(l==r) {
tree[o]=sumo[o] = mex1[l];
return;
}
int m=(l+r)/2;
build(lson);
build(rson);
pushup(l,r,o);
}
inline void gao(int l,int r, int o, int v)
{
tree[o] = v;
lazy[o] = v;
sumo[o] = 1LL * v * (r - l + 1);
}
void pushdown(int l,int r,int o)
{
if(lazy[o] > -1)
{
int m=(l+r)/2;
int v = lazy[o];
gao(lson, v);
gao(rson, v);
lazy[o] = -1;
}
}
void update(int L,int R,int v, int l,int r,int o)
{
if(L<=l&&r<=R) {
gao(l,r,o, v);
return;
}
int m=(l+r)/2;
pushdown(l,r,o);
if(L<=m) update(L,R,v, lson);
if(m<R) update(L,R,v, rson);
pushup(l,r,o);
}
int Upper_bound(int l,int r,int o,int v)
{
if(l==r) return l;
pushdown(l,r,o);
int m=(l+r)/2;
if(tree[ls] > v) return Upper_bound(lson, v);
if(tree[rs] > v) return Upper_bound(rson, v);
return r+1;
}
int main()
{
while(cin>>n, n)
{
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++)
{
scanf("%d",a+i);
if(a[i]>Lim) a[i] = Lim;
}
getMex1();
getNext();
build(1, n, 1);
long long ret = 0;
for(int i=1;i<=n;i++)
{
ret += sumo[1];
int L = Upper_bound(1,n,1, a[i]);
int R = next[i] - 1;
if(L <= R) update(L,R,a[i], 1,n,1);
update(i,i,0, 1,n,1);
if(tree[1]==0) break;
}
printf("%I64d\n", ret);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: