C

题目链接:Here

设ans[i]为以前i个数为结尾的序列的总数,last[x]为以数x为结尾,长度大于1的序列的总数,vis[x]表示数x是否出现过,第i个数a[i]=x。

若x没有出现过,则以第i个数为结尾的序列的个数为 ans[i-1]+1  (以 前i个数为结尾的序列后面加上一个x,在加上一个长度为1的序列x)
若x出现过,则以第i个数为结尾的序列的个数为  ans[i-1]-last[x]  (以 前i个数为结尾的序列后面加上一个x,但因为x曾经出现过,所以减去重复的部分last[x],另外取模的时候要注意加上mod。

然后更新last[x]的值,显然这个值为 ans[i-1].

最后ans[n]即为所求的答案。

AC Code:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 const long M=1100000;
 5 const long mod=1000000007;
 6 long last[M],vis[M],n,ans;
 7 int main(){
 8     while (~scanf("%d",&n)){
 9         memset(vis,0,sizeof(vis));
10         memset(last,0,sizeof(last));
11         ans=0;
12         for (long i=1;i<=n;++i){
13             long x; 
14             scanf("%d",&x);
15             if (!vis[x]){
16                 last[x]=ans;
17                 ans=(ans+ans+1)%mod;
18                 vis[x]=1;
19             }
20             else{
21                 long temp=ans;
22                 ans=((temp-last[x]+mod)%mod+ans)%mod;
23                 last[x]=temp;
24             }
25         }
26         printf("%d
",ans);
27     }
28     return 0;
29 }

By 桢旭

原文地址:https://www.cnblogs.com/scnuacm/p/3226703.html