题目2 : Rikka with Subsequence
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
-
4 abdb 0 0 0 0
样例输出
-
14
描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:
勇太有一个长度为n的字符串s,现在他对这个字符串进行了一些操作,在操作之后第i个字符有Ai%的概率被删除。现在他想要知道在操作之后得到的新的字符串的本质不同的子序列个数的期望值(包括空串)。
字符串s是字符串t的子序列当且仅当删除了t中若干个位置之后可以得到字符串s。
当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入
第一行输入一个正整数n。
第二行输入一个长度为n的只包含小写字母的字符串。
第二行输入n个空格隔开的数字表示数组A。
n ≤ 5 × 105, 0 ≤ Ai ≤ 100
输出
输出一个整数表示答案对998244353取模后的值。
额外样例
输入 | 输出 |
4 | 311951365 |
程序如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define maxn 500100
#define mod 998244353
int qpow(int a,int b,int p){
int tmp=a,ans=1;
for(int i=0;b>>i;i++,tmp=1ll*tmp*tmp%p)
if((b>>i)&1)ans=1ll*ans*tmp%p;
return ans;
}
int dp[maxn],a[maxn],fa[maxn],n,ans,last[26];
char str[maxn];
int main(){
scanf("%d%s",&n,str+1);
int inx=qpow(100,mod-2,mod);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
a[i]=1ll*(100-a[i])*inx%mod;
}
dp[0]=1;
for(int i=0;i<26;++i)last[i]=1;
for(int i=1;i<=n;++i){
dp[i]=1ll*last[str[i]-'a']*a[i]%mod;
for(int j=0;j<26;++j)if(j+'a'!=str[i])
last[j]=(last[j]+dp[i])%mod;
ans=(ans+dp[i])%mod;
}
printf("%d",(ans+1+mod)%mod);
}