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;
}

猜你喜欢

转载自www.cnblogs.com/luoyibujue/p/10112835.html