1. 程式人生 > >FZU2129 子序列個數

FZU2129 子序列個數

求不同的子序列個數

/*

記錄下每個元素的同色前驅, 然後容斥思想
dp[i]表示前i個數的不同子序列個數, 轉移的時候利用字首和思想
dp[i] = dp[i - 1] << 1
dp[i] += (pre[a[i]] ? -dp[pre[a[i]]] : 1);
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<map>
#include
<set> #include<cmath> #define M 1000100 #define ll long long const int mod = 1000000007; using namespace std; int read() { int nm = 0, f = 1; char c = getchar(); for(; !isdigit(c); c = getchar()) if(c == '-') f = -1; for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f; } ll dp[M], a[M], last[M]; int main() { //freopen(".in", "r", stdin), freopen(".out", "w", stdout); int n = read(); for(int i = 1; i <= n; i++) { a[i] = read(); dp[i] = dp[i - 1] << 1; if(last[a[i]]) dp[i] -= dp[last[a[i]]];
else dp[i] |= 1; dp[i] += mod; dp[i] %= mod; } cout << dp[n] << "\n"; return 0; }