• 【AGC040C】Neither AB nor BA


    题目

    题目链接:https://atcoder.jp/contests/agc040/tasks/agc040_c
    给定一个 (n),求有多少个长度为 (n) 且只包含 ABC 的字符串满足以下条件:

    • 每次可以选定一个长度为 (2) 的子串删掉,且这个子串不为 ABBA,直到整个字符串被删除。

    (nleq 10^7)(n) 是偶数。

    思路

    对于一个合法的字符串 (s),把它偶数位置上的字符 AB 全部取反,这样原问题等价于在新串上每次删除长度为 (2) 的子串且不为 AABB。因为每一个合法字符串之间都是一一对应的。
    那么新问题只需要满足这个字符串 AB 的出现次数不超过严格一半即可。容斥一下直接随便计数就好了。
    时间复杂度 (O(n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=10000010,MOD=998244353;
    int n;
    ll ans,fac[N],inv[N];
    
    ll fpow(ll x,ll k)
    {
    	ll ans=1;
    	for (;k;k>>=1,x=x*x%MOD)
    		if (k&1) ans=ans*x%MOD;
    	return ans;
    }
    
    ll C(int n,int m)
    {
    	return fac[n]*inv[m]%MOD*inv[n-m]%MOD;
    }
    
    int main()
    {
    	scanf("%d",&n);
    	fac[0]=inv[0]=1;
    	for (int i=1;i<=n;i++) fac[i]=fac[i-1]*i%MOD;
    	inv[n]=fpow(fac[n],MOD-2);
    	for (int i=n-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%MOD;
    	ans=fpow(3,n);
    	for (int i=n/2+1;i<=n;i++)
    		ans=(ans-2LL*C(n,i)*fpow(2,n-i))%MOD;
    	cout<<(ans%MOD+MOD)%MOD;
    	return 0;
    }
    
  • 相关阅读:
    day06 tar命令使用,vim简单操作以及linux开机过程
    day05 创建用户过程、文件夹,文件等权限修改等
    简单算法
    day04
    day03
    Vim常用快捷键
    day02
    ssh注解开发
    spring07 JDBC
    spring06Aop
  • 原文地址:https://www.cnblogs.com/stoorz/p/15014730.html
Copyright © 2020-2023  润新知