E题

容易想到,只考虑前i个数的序列乘积的个位只有10种状态:个位为0~9

定义f[i][j]:前i个数中,序列乘积的个位为j的方案数

贡献:前i个数中,以a[i]结尾的序列且乘积个位为6能提供的贡献

这里与题意序列贡献有所不同,因为我们根据f[i][j]定义已知序列在前面的方案总数,我们只考虑当前序列作为序列的前缀还会在后面还会出现多少次,出现多少次就贡献了多少答案

结论:以a[i]结尾的序列作为序列的前缀还能在后面出现的次数为2^(n-i)(后面每个数有可选可不选两种抉择)

用样例一解释

3

4 4 6

序列[4,4]贡献答案 2(446 和 44_)(f[1][4]×a[2]×2^(3-2)==2)

序列[6]贡献答案 1 (6)(f[2][1]*a[3]==1)

序列[4,4,6]贡献答案 1 (446)(f[2][6]*a[3]==1)

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int mod=1e9+7;
int n,ans,a[100005],f[100005][10];

int quick_pow(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b&1)res=res*a%mod;
        a=a*a%mod;
        b/=2;
    }
    return res;
}

void solved()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    
    //f[i][j]:前i个数中,序列乘积的个位为j的方案数
    f[0][1]=1;//初值
    for(int i=1;i<=n;i++)
        for(int j=0;j<=9;j++)//状态转移方程
        {
            f[i][j*a[i]%10]=(f[i][j*a[i]%10]+f[i-1][j])%mod;//以a[i]结尾的序列
            f[i][j]=(f[i][j]+f[i-1][j])%mod;//非a[i]结尾的序列
        }
        
    for(int i=1;i<=n;i++)
        ans=(ans+(f[i][6]-f[i-1][6]+mod)%mod*quick_pow(2,n-i)%mod)%mod;//以a[i]结尾的序列乘积贡献答案
    cout<<ans;
}

signed main()
{
    solved();
    return 0;
}