Codeforces1426 F.Number of Subsequences(枚举,组合数学推式子)

题意:

给定一个只包含“abc?”的字符串,其中’?'可以替换为abc的任意一种。
问对于所有可能的串,子序列abc的总和是多少。
答案对1e9+7取模。

数据范围:n<=2e5

解法:

三 元 组 统 计 的 套 路 : 枚 举 中 间 的 b , 统 计 两 端 的 a 和 c 计 算 贡 献 。 三元组统计的套路:枚举中间的b,统计两端的a和c计算贡献。 bac

假 设 左 边 有 x 个 ′ a ′ , y 个 ′ ? ′ 。 假设左边有x个'a',y个'?'。 xay?

假 设 i 个 变 成 a , 那 么 y − i 个 就 变 成 b / c , 方 案 数 为 C ( y , i ) ∗ 2 y − i 假设i个变成a,那么y-i个就变成b/c,方案数为C(y,i)*2^{y-i} iayib/cC(y,i)2yi

加 上 固 定 的 x 个 , 那 么 可 能 的 a 的 个 数 总 为 : ∑ i = 0 y C ( y , i ) ∗ 2 y − i ∗ ( x + i ) 加上固定的x个,那么可能的a的个数总为:\sum_{i=0}^yC(y,i)*2^{y-i}*(x+i) x,a:i=0yC(y,i)2yi(x+i)

将 式 子 拆 开 变 为 : 将式子拆开变为: :

∑ i = 0 y C ( y , i ) ∗ 2 y − i ∗ i + ∑ i = 0 y C ( y , i ) ∗ 2 y − i ∗ x \sum_{i=0}^yC(y,i)*2^{y-i}*i+\sum_{i=0}^yC(y,i)*2^{y-i}*x i=0yC(y,i)2yii+i=0yC(y,i)2yix

= ∑ i = 0 y C ( y , i ) ∗ 2 y − i ∗ i + ( 1 + 2 ) y ∗ x =\sum_{i=0}^yC(y,i)*2^{y-i}*i+(1+2)^{y}*x =i=0yC(y,i)2yii+(1+2)yx

= ∑ i = 0 y C ( y , i ) ∗ 2 y − i ∗ i + 3 y ∗ x =\sum_{i=0}^yC(y,i)*2^{y-i}*i+3^{y}*x =i=0yC(y,i)2yii+3yx

因 为 C ( n , m ) = n ! m ! ∗ ( n − m ) ! , 因 此 式 子 变 为 因为C(n,m)=\frac {n!}{m!*(n-m)!},因此式子变为 C(n,m)=m!(nm)!n!,

∑ i = 0 y y ! i ! ∗ ( y − i ) ! ∗ 2 y − i ∗ i + 3 y ∗ x \sum_{i=0}^y \frac {y!}{i!*(y-i)!}*2^{y-i}*i+3^{y}*x i=0yi!(yi)!y!2yii+3yx

= ∑ i = 0 y y ! ( i − 1 ) ! ∗ ( y − i ) ! ∗ 2 y − i + 3 y ∗ x =\sum_{i=0}^y \frac {y!}{(i-1)!*(y-i)!}*2^{y-i}+3^{y}*x =i=0y(i1)!(yi)!y!2yi+3yx

= y ∗ ∑ i = 0 y ( y − 1 ) ! ( i − 1 ) ! ∗ ( y − i ) ! ∗ 2 y − i + 3 y ∗ x =y*\sum_{i=0}^y \frac {(y-1)!}{(i-1)!*(y-i)!}*2^{y-i}+3^{y}*x =yi=0y(i1)!(yi)!(y1)!2yi+3yx

= y ∗ ∑ i = 0 y ( y − 1 ) ! ( i − 1 ) ! ∗ ( y − i ) ! ∗ 2 y − i + 3 y ∗ x =y*\sum_{i=0}^y \frac {(y-1)!}{(i-1)!*(y-i)!}*2^{y-i}+3^{y}*x =yi=0y(i1)!(yi)!(y1)!2yi+3yx

= y ∗ ∑ i = 0 y C ( y − 1 , y − i ) ∗ 2 y − i + 3 y ∗ x =y*\sum_{i=0}^yC(y-1,y-i)*2^{y-i}+3^{y}*x =yi=0yC(y1,yi)2yi+3yx

= y ∗ ∑ i = 0 y C ( y − 1 , y − i ) ∗ 2 y − i + 3 y ∗ x =y*\sum_{i=0}^yC(y-1,y-i)*2^{y-i}+3^{y}*x =yi=0yC(y1,yi)2yi+3yx

左 边 当 i = 0 时 = 0 , 那 么 下 标 可 以 改 为 从 i = 1 开 始 左边当i=0时=0,那么下标可以改为从i=1开始 i=0=0,i=1

= y ∗ ∑ i = 1 y C ( y − 1 , y − i ) ∗ 2 y − i + 3 y ∗ x =y*\sum_{i=1}^yC(y-1,y-i)*2^{y-i}+3^{y}*x =yi=1yC(y1,yi)2yi+3yx

y − i 可 以 替 换 为 i , 因 为 是 对 称 的 y-i可以替换为i,因为是对称的 yii,

= y ∗ ∑ i = 0 y − 1 C ( y − 1 , i ) ∗ 2 i + 3 y ∗ x =y*\sum_{i=0}^{y-1}C(y-1,i)*2^i+3^y*x =yi=0y1C(y1,i)2i+3yx

= y ∗ ( 2 + 1 ) y − 1 + 3 y ∗ x =y*(2+1)^{y-1}+3^y*x =y(2+1)y1+3yx

= 3 y − 1 ∗ y + 3 y ∗ x =3^{y-1}*y+3^y*x =3y1y+3yx

预 处 理 p o w ( 3 ) 即 可 预处理pow(3)即可 pow(3)

上 面 计 算 的 是 左 边 的 数 量 , 右 边 一 样 的 上面计算的是左边的数量,右边一样的 ,

参 考 : h t t p s : / / w w w . l u o g u . c o m . c n / b l o g / Z i g Z a g K m p / C F 1426 F − s o l u t i o n 参考:https://www.luogu.com.cn/blog/ZigZagKmp/CF1426F-solution https://www.luogu.com.cn/blog/ZigZagKmp/CF1426Fsolution

code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e5+5;
const int mod=1e9+7;
char s[maxm];
int p3[maxm];
int lx[maxm],rx[maxm];
int ly[maxm],ry[maxm];
int n;
void init(){
    p3[0]=1;
    for(int i=1;i<maxm;i++)p3[i]=1ll*p3[i-1]*3%mod;
}
signed main(){
    init();
    cin>>n;
    scanf("%s",s+1);
    for(int i=1;i<=n;i++){
        lx[i]=lx[i-1];
        ly[i]=ly[i-1];
        if(s[i]=='a')lx[i]++;
        else if(s[i]=='?')ly[i]++;
    }
    for(int i=n;i>=1;i--){
        rx[i]=rx[i+1];
        ry[i]=ry[i+1];
        if(s[i]=='c')rx[i]++;
        else if(s[i]=='?')ry[i]++;
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        if(s[i]=='b'||s[i]=='?'){
            int L=0;
            L+=p3[ly[i-1]]*lx[i-1]%mod;
            if(ly[i-1])L+=p3[ly[i-1]-1]*ly[i-1]%mod;
            int R=0;
            R+=p3[ry[i+1]]*rx[i+1]%mod;
            if(ry[i+1])R+=p3[ry[i+1]-1]*ry[i+1]%mod;
            ans=(ans+L*R)%mod;
        }
    }
    cout<<ans<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值