hdu 4747(DP?线性递推)

                                               Mex

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 3876    Accepted Submission(s): 1290

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

 Recommend

liuyiding

题意:给n个数,求所有区间内没有出现的最小非负整数和。

思路:有一个性质,对于mex(i,j),i固定,j增加,则mex(i,j)非严格递增。

       记F[i]为以i结束的所有区间的值的和,则我们可以从F[i]推到F[i+1];记第i+1位的数位A[i+1],则我们只用考虑大于等于A[i+1]的数对F[i+1]=F[i]+?产生的影响(注意add的值,因为<A[I+1]-1的数不产生增量,A[I+1]-1的数之后会得到统计)
      记S[i]表示0到i的所有数都出现的最小位置,如 数列 7 3 2 1 4 0 5 6 s[0]=6 s[1]=4 s[2]=3 s[3]=2 s[4]=2 s[5]=2 s[6]=2 s[7]=1 (倒着往前的)
如果j(j>=a[i+1])出现在1~i区间中,比较j最晚出现的位置与覆盖完全的1~j-1的最小位置的较小位置k,那么区间j的前一次出现的位置到k位置这个区间内所有点到i位置的值都+1。
       为什么是j最晚出现的位置:例子是 8 8 8 6 7 3 2 1 4 0 5 6,做6的时候计算一下

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<vector>
#include<stack>
#define ll long long
#define maxn 4001000
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define rep(i,a,b) for(int i=a;i<=b;i++)
const ll P=1e9+7;
using namespace std;
map<int,int> p;
int n,a[201000],pre[201000],s[201000];
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
    	if(n==0) break;
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	memset(pre,0,sizeof(pre));
    	memset(s,0,sizeof(s));
    	ll ans=0,add=0;
		for(int i=1;i<=n;i++,ans+=add)
		if(a[i]<=n)
		{
			int temp=pre[a[i]];
			pre[a[i]]=i;
			for(int j=a[i];j<=n;j++)
			{
				s[j]=j==0?pre[j]:min(s[j-1],pre[j]);
				if(s[j]>temp) add+=s[j]-temp;
				else break;
			}
		}
		printf("%lld\n",ans); 
	}
}
posted @ 2018-09-04 13:47  The-Pines-of-Star  阅读(263)  评论(0编辑  收藏  举报