题目链接: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 桢旭