子序列个数

来源:互联网 发布:那个人好像一条狗 知乎 编辑:程序博客网 时间:2024/06/03 20:31


题目大致描述如下
给定一个正整数序列,序列中元素的个数和元素值大小都不超过10^5, 求其所有子序列的个数。注意相同的只算一次:例如 {1,2,1}有子序列{1} {2} {1,2} {2,1}和{1,2,1}。最后结果对10^9 + 7取余数。

输入

第1行:一个数N,表示序列的长度(1 <= N <= 100000)第2 - N + 1行:序列中的元素(1 <= a[i] <= 100000)

输出

输出a的不同子序列的数量Mod 10^9 + 7。

输入示例

41232

输出示例

13


代码如下:

#include <iostream>#include <stdio.h>#include <algorithm>#define inf 1000000007using namespace std;int main(){    int n;    cin>>n;    long long int num[n+1],last[n+1],dp[n+1];    fill(last,last+n+1,0);    fill(dp,dp+n+1,0);    for(int i=1;i<=n;i++)scanf("%lld",&num[i]);    dp[1]=1;last[num[1]]=1;    //printf("\n*************************\n");    for(int i=2;i<=n;i++){        dp[i]=(dp[i-1]+1)*2-1;        dp[i]%=inf;        if(last[num[i]])dp[i]=(dp[i]-(dp[last[num[i]]-1]+1)+inf)%inf;        last[num[i]]=i;    }    printf("%lld\n",dp[n]);}

这里只解释一个问题,为什么
if(last[num[i]])dp[i]=(dp[i]-(dp[last[num[i]]-1]+1)+inf)%inf;

而不是
if(last[num[i]])dp[i]=(dp[i]-(dp[last[num[i]]-1]+1))%inf;

原因很简单,dp[i]是很有可能小于dp[last[num[i]]-1]+1 的,这为什么呢?因为很有可能dp[i]会因为大于10^9而取余的很小而此时dp[last[num[i]]-1]+1却没有。

在加上inf之后其值是一定大于0的,这时就可以放心取余了,反正加个inf和不加一样,你高兴了加仨也行,反正超不过long long

0 0