题目描述
\,\,\,\,\,\,\,\,\,\,对于一个长度为 mmm 的整数序列 {b1,b2,…,bm}\{b_1,b_2,\dots,b_m\}{b1,b2,…,bm},定义 fi=b1×b2×⋯×bif_i = b_1 \times b_2 \times \cdots \times b_ifi=b1×b2×⋯×bi ,即前 iii 项的乘积。这个序列的权值即为 f1,f2,…,fmf_1, f_2, \dots, f_mf1,f2,…,fm 中个位数是 666 的数字个数。
\,\,\,\,\,\,\,\,\,\,小红有一个长度为 nnn 的整数序列 {a1,a2,…,an}\{a_1,a_2,\dots,a_n\}{a1,a2,…,an},她想知道这个序列全部 2n−12^n-12n−1 个非空子序列的权值和是多少。
\,\,\,\,\,\,\,\,\,\,如果序列 aaa 可以通过删除序列 bbb 中的若干(可能为零或全部)元素得到,则序列 aaa 是序列 bbb 的子序列。
输入描述:
\,\,\,\,\,\,\,\,\,\,第一行输入一个整数 n(1≤n≤105)n \left(1 \leq n \leq 10^5\right)n(1≤n≤105) 代表序列中元素的数量。 \,\,\,\,\,\,\,\,\,\,第二行输入 nnn 个整数 a1,a2,⋯ ,an(1≤ai≤109)a_1, a_2, \cdots, a_n \left(1 \leq a_i \leq 10^9\right)a1,a2,⋯,an(1≤ai≤109) 代表序列元素。
输出描述:
\,\,\,\,\,\,\,\,\,\,在一行上输出一个整数,输出一个整数,表示全部子序列的权值和。由于答案可能很大,请将答案对 (109+7)(10^9+7)(109+7) 取模后输出。
示例1
输入
复制3 4 4 6
3 4 4 6
输出
复制4
4
说明
\,\,\,\,\,\,\,\,\,\,对于子序列 [4][4][4] ,没有贡献; \,\,\,\,\,\,\,\,\,\,对于子序列 [6][6][6] ,f={6}f=\{6\}f={6} 贡献为 111 ; \,\,\,\,\,\,\,\,\,\,对于子序列 [4,4][4,4][4,4] ,f={4,16}f=\{4,16\}f={4,16} 贡献为 111 ; \,\,\,\,\,\,\,\,\,\,对于子序列 [4,6][4,6][4,6] ,f={4,24}f=\{4,24\}f={4,24} ,没有贡献; \,\,\,\,\,\,\,\,\,\,对于子序列 [4,4,6][4,4,6][4,4,6] ,f={4,16,96}f=\{4,16,96\}f={4,16,96} 贡献为 222 。
示例2
输入
复制5 1 2 3 4 4
5 1 2 3 4 4
输出
复制12
12
做法
摘抄:
容易想到,只考虑前i个数的序列乘积的个位只有10种状态:个位为0~9
定义f[i][j]:前i个数中,序列乘积的个位为j的方案数
贡献:前i个数中,以a[i]结尾的序列且乘积个位为6能提供的贡献
这里与题意序列贡献有所不同,因为我们根据f[i][j]定义已知序列在前面的方案总数,我们只考虑当前序列作为序列的前缀还会在后面还会出现多少次,出现多少次就贡献了多少答案
结论:以a[i]结尾的序列作为序列的前缀还能在后面出现的次数为2^(n-i)(后面每个数有可选可不选两种抉择)
#include<bits/stdc++.h>
using namespace std;
int n;
long long a[100010];
long long dp[100010][12];
long long ans;
const long long mod=1e9+7;
long long ksm(long long a,long long b){
long long ans=1;
while(b){
if(b%2) ans=ans*a%mod;
b/=2;
a=a*a%mod;
}
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
dp[0][1]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<=9;j++){
dp[i][j*a[i]%10]+=dp[i-1][j];
dp[i][j*a[i]%10]%=mod;
dp[i][j]+=dp[i-1][j];
dp[i][j]%=mod;
}
}
for(int i=1;i<=n;i++){
//负数情况也能处理???
ans=(ans+(dp[i][6]-dp[i-1][6]+mod)%mod*ksm(2,n-i)%mod)%mod;
}
cout<<ans<<endl;
}