hiho 1412 : Rikka with Subsequence

来源:互联网 发布:newman 网络引论 编辑:程序博客网 时间:2024/06/04 19:55

#1412 : Rikka with Subsequence


时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:

勇太有一个长度为n的字符串s,现在他对这个字符串进行了一些操作,在操作之后第i个字符有Ai%的概率被删除。现在他想要知道在操作之后得到的新的字符串的本质不同的子序列个数的期望值(包括空串)。

字符串s是字符串t的子序列当且仅当删除了t中若干个位置之后可以得到字符串s。

当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?

输入

第一行输入一个正整数n。

第二行输入一个长度为n的只包含小写字母的字符串。

第二行输入n个空格隔开的数字表示数组A。

n ≤ 5 × 105, 0 ≤ Ai ≤ 100

输出

输出一个整数表示答案对998244353取模后的值。

额外样例

输入输出

4
abdb
50 50 50 50

311951365


样例输入
4abdb0 0 0 0
样例输出
14




#include <bits/stdc++.h>using namespace std;typedef pair<int,int> pll;typedef long long ll;const int mod=998244353;int qpow(int res,int p){    int ans=1;    while(p)    {        if(p&1)ans=1LL*ans*res%mod;        res=1LL*res*res%mod;        p>>=1;    }    return ans;}const int N=5*1e5+100;char s[N];int a[N];int f[N],sum[N];int last[N];int main(){    int n;    int inv=828542813;     //inv=qpow(100,mod-2);    while(scanf("%d",&n)!=EOF)    {        scanf("%s",s+1);        for(int i=1; i<=n; i++)            scanf("%d",&a[i]);        f[0]=1;        memset(last,0,sizeof(last));        memset(sum,0,sizeof(sum));        for(int i=1; i<=n; i++)        {            int pos=sum[last[s[i]-'a']];            f[i]=((100-a[i])*(f[i-1]*2LL%mod-pos)%mod+1LL*a[i]*f[i-1]%mod)%mod*inv%mod;            sum[i]=(1LL*(100-a[i])*f[i-1]%mod+1LL*pos*a[i]%mod)%mod*inv%mod;            last[s[i]-'a']=i;        }        printf("%d\n",(f[n]+mod)%mod);    }    return 0;}

0 0
原创粉丝点击