b_51_子序列的个数(先从可重复的情况出发+记录前一个数的位置)

请求出数组a的不同子序列的数量。1<=N<=100000

思路:允许重复的情况下的子序列的状态表示为f[i]=2*f[i-1]+1(n=1时,有一个;n=2时,有三个;n=3时,有七个...)
但怎么去除重复的统计呢?当位置a[p]==a[i]时(p<i),p前面的元素和a[i]会形成和a[p]与p前的元素相同的子序列,所以这部分是重复的
f[i]=f[i-1]*2-f[last[a[i]-1]

import java.util.*;
import java.math.*;
import java.io.*;
class Solution {
    void init() {
        Scanner sc = new Scanner(new BufferedInputStream(System.in));
        int n=sc.nextInt(), a[]=new int[n+5], f[]=new int[n+5], last[]=new int[(int) 1e5+5], mod=(int)1e9+7;
        for (int i=1; i<=n; i++) {a[i]=sc.nextInt(); last[a[i]]=-1;}
        for (int i=1; i<=n; i++) {
            if (last[a[i]]==-1)  f[i]=(2*f[i-1]+1)%mod;
            else f[i]=(f[i-1]*2-f[last[a[i]]-1])%mod; //重复元素a[p]的上一个位置,即减去f[p-1]
            f[i]=(f[i]+mod)%mod; last[a[i]]=i;             
        }
        System.out.println(f[n]);
    }
}
public class Main{
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
        s.init();
    }
}
posted @ 2020-10-28 11:23  童年の波鞋  阅读(78)  评论(0编辑  收藏  举报