CodeForces 794 G.Replace All

解题思路

首先如果字符串 \(A, B\) 没有匹配,那么二元组 \((S, T)\) 合法的一个必要条件是存在正整数对 \((x,y)\),使得 \(xS=yT\),其中 \(xS\) 是将字符串 \(S\) 复制 \(x\) 遍后得到的字符串,\(yT\) 是将字符串 \(T\) 复制 \(T\) 遍后得到的字符串。由于 \(A,B\) 直接匹配的情况比较容易讨论,下面没有特殊说明,都是 \(A,B\) 没有直接匹配的情况。

这个条件的实际意义是通过这个二元组 \((S,T)\) 转化后,能将 \(x\) 个 \('a'\) 组成的子串与 \(y\) 个 \('b'\) 组成的子串通配,必要性可以根据这个感性理解,下面来证明满足这个条件的二元组的一些性质。

对于字符串 \(C=xS=yT\) ,显然存在周期 \(x\) 和周期 \(y\) ,根据周期定理 \(\gcd(x,y)\) 也是 \(C\) 的一个周期,其也是 \(S,T\) 的一个周期,我们令 \(C[1:\gcd(x,y)]=D\) ,那么 \(S=\dfrac{y}{\gcd(x,y)}D,T=\dfrac{x}{\gcd(x,y)}D\) 。用 \(+\) 表示字符串的拼接,可以得到 \(S+T=T+S=\dfrac{xy}{\gcd(x,y)}D\) 。也就是用这个二元组转化后,任意两个相邻的字符 \('a','b'\) 交换后得到的字符串不变,最终的字符串只与字符 \('a','b'\) 的数量用关。

假设将 \('?'\) 填好之后,令 \(\Delta a\) 表示 \(A\) 中 \('a'\) 的数量与 \(B\) 中 \('a'\) 的数量之差,\(\Delta b\) 表示 \(A\) 中 \('b'\) 的数量与 \(B\) 中 \('b'\) 的数量之差,此时如果 \(\Delta a \Delta b\geq0\) 且 \(\Delta a,\Delta b\) 不同时等于 \(0\) ,那么不存在满足条件的合法二元组。

如果 \(\Delta a=0,\Delta b=0\) ,那么任意一个满足条件的合法二元组都可以,其中一个 \(\gcd(x,y)=g\) 的合法二元组的方案数就是 \(2^g\) (考虑字符串 \(D\) 的每一位是怎么填的即可),那么只需要容斥出所有 \(\gcd(x,y)=i\) 的对数即可。

否则,满足条件的 \(x, y\) 的比值是 \(\dfrac{|\Delta a|}{|\Delta b|}\) ,令 \(g=\gcd(\Delta a,\Delta b)\) ,枚举 \(D\) 的长度,方案数就是

\[2^{\dfrac{n}{\dfrac{\max(|\Delta a|,|\Delta b|)}{g}}+1}-2
\]

现在考虑 \('?'\) 的影响,令 \(cntA\) 为 \(A\) 中 \('?'\) 个数,\(cntB\) 为 \(B\) 中 \('?'\) 个数,那么填 \('?'\) 的影响就是让 \(\Delta a\) 加上一个整数 \(d\),\(\Delta b\) 加上 \(cntA-cntB-d\),这样选的方案数是 \({cntA+cntB}\choose{cntB+d}\) ,推导可以把方案数的和式列出来然后展开,当然你要做卷积也是可以的。(模数 \(10^9+7\)) ,然后只需要枚举一下 \('?'\) 贡献的 \(d\) 的值这一部分就算出来了。

注意前面提到的都是 \(A,B\) 没有直接匹配的情况,对于 \(A,B\) 在填完 \('?'\) 之后能直接匹配的情况,所有的二元组都是合法的,只需要把之前没算的部分在这里算上即可,总的复杂度是 \(\mathcal O(n\log n)\) 。

code

/*program by mangoyang*/
#include <bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 1000005, mod = 1e9 + 7;
char s[N], t[N];
int inv[N], js[N], pw[N], f[N], cnts, cntt, da, db, lens, lent, n, ans, total;
inline int Pow(int a, int b){
int ans = 1;
for(; b; b >>= 1, a = 1ll * a * a % mod)
if(b & 1) ans = 1ll * ans * a % mod;
return ans;
}
inline int C(int x, int y){
return 1ll * js[x] * inv[y] % mod * inv[x-y] % mod;
}
int main(){
scanf("%s", s + 1), scanf("%s", t + 1), read(n);
lens = strlen(s + 1), lent = strlen(t + 1);
for(int i = 1; i <= lens; i++){
if(s[i] == 'A') da++; if(s[i] == 'B') db++; if(s[i] == '?') cnts++;
}
for(int i = 1; i <= lent; i++){
if(t[i] == 'A') da--; if(t[i] == 'B') db--; if(t[i] == '?') cntt++;
}
inv[0] = js[0] = pw[0] = 1;
for(int i = 1; i <= n + 1; i++) pw[i] = 2ll * pw[i-1] % mod;
for(int i = 1; i <= lens + lent; i++)
js[i] = 1ll * js[i-1] * i % mod, inv[i] = Pow(js[i], mod - 2);
for(int i = n; i; i--){
f[i] = 1ll * (n / i) * (n / i) % mod;
for(int j = i + i; j <= n; j += i) (f[i] += mod - f[j]) %= mod;
total = (total + 1ll * f[i] * pw[i] % mod) % mod;
}
for(int d = -cntt; d <= cnts; d++){
int A = da + d, B = db + cnts - cntt - d, x = C(cnts + cntt, cntt + d);
if(!A && !B) (ans += 1ll * x * total % mod) %= mod;
if(1ll * A * B >= 0) continue;
int g = __gcd(abs(A), abs(B));
A = abs(A) / g, B = abs(B) / g;
(ans += (1ll * x * (pw[n/max(A,B)+1] - 2) + mod) % mod) %= mod;
}
if(lens == lent){
int flag = 1, res = 1;
for(int i = 1; i <= lens; i++){
if(s[i] != '?' && t[i] != '?' && s[i] != t[i]) flag = 0;
if(s[i] == '?' && t[i] == '?') res = 2ll * res % mod;
}
if(!flag) return cout << ans << endl, 0;
(ans += 1ll * res * (1ll * (pw[n+1] - 2) * (pw[n+1] - 2) % mod - total) % mod) %= mod;
ans = (ans % mod + mod) % mod;
}
cout << ans << endl;
return 0;
}

CodeForces 794 G.Replace All的更多相关文章

  1. [codeforces 549]G. Happy Line

    [codeforces 549]G. Happy Line 试题描述 Do you like summer? Residents of Berland do. They especially love ...

  2. Codeforces 1207 G. Indie Album

    Codeforces 1207 G. Indie Album 解题思路 离线下来用SAM或者AC自动机就是一个单点加子树求和,套个树状数组就好了,因为这个题广义SAM不能存在 \(len[u] = l ...

  3. codeforces 659 G. Fence Divercity 组合数学 dp

    http://codeforces.com/problemset/problem/659/G 思路: f(i,0/1,0/1) 表示到了第i个,要被切的块开始了没有,结束了没有的状态的方案数 递推看代 ...

  4. Codeforces 803 G. Periodic RMQ Problem

    题目链接:http://codeforces.com/problemset/problem/803/G 大致就是线段树动态开节点. 然后考虑到如果一个点还没有出现过,那么这个点显然未被修改,就将这个点 ...

  5. Codeforces 954 G. Castle Defense

    http://codeforces.com/problemset/problem/954/G 二分答案 检验的时候,从前往后枚举,如果发现某个位置的防御力<二分的值,那么新加的位置肯定是越靠后越 ...

  6. Codeforces 746 G. New Roads

    题目链接:http://codeforces.com/contest/746/problem/G mamaya,不知道YY了一个什么做法就这样过去了啊 2333 首先我显然可以随便构造出一棵树满足他所 ...

  7. Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS

    G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组 ...

  8. codeforces 626 G. Raffles(线段树+思维+贪心)

    题目链接:http://codeforces.com/contest/626/problem/G 题解:这题很明显买彩票肯定要买贡献最大的也就是说买p[i]*(num[i]+1)/(num[i]+a[ ...

  9. codeforces 794 C. Naming Company(贪心)

    题目链接:http://codeforces.com/contest/794/problem/C 题意:有两个人每个人都有一个长度为n的字符串,两人轮流拿出一个字符串,放在一个长度为n的字符串的指定位 ...

随机推荐

  1. python爬虫 scrapy3_ 安装指南

      安装指南 安装Scrapy 注解 请先阅读 平台安装指南. 下列的安装步骤假定您已经安装好下列程序: Python 2.7 Python Package: pip and setuptools. ...

  2. Java基础-Java中23种设计模式之常用的设计模式

    Java基础-Java中23种设计模式之常用的设计模式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.设计模式分类 设计模式是针对特定场景给出的专家级的解决方案.总的来说设 ...

  3. scala 资料集结

    Scala入门到精通 http://lib.csdn.net/base/scala/structure http://hongjiang.info/scala/ http://blog.csdn.ne ...

  4. python 基础 元组()

    # 元组 应用场景 # 尽管 Python的列表中可以存储不同类型的数据 # 但是在开发中,更多的应用场景是 # 1.列表存储相同类型的数据 # 2.通过迭代遍历,在循环体内部,针对列表中的每一项元素 ...

  5. javascript鼠标拖拽的那些事情

    <html> <head> <title>javascript鼠标拖拽的那些事情</title> <meta http-equiv="C ...

  6. [整] Android ListView 去除边缘阴影、选中色、拖动背景色等

    以下是通过XML定义的方式实现,如果需要通过代码实现,找到对应是set方式设置即可. 去除ListView滑到顶部和底部时边缘的黑色阴影: android:fadingEdge="none& ...

  7. MongoDB 之 手把手教你增删改查 MongoDB - 2

    我们在  MongoDB 之 你得知道MongoDB是个什么鬼 MongoDB - 1  中学习了如果安装部署一个 MongoDB 如果没看到我的金玉良言的话,就重新打开一次客户端和服务端吧 本章我们 ...

  8. 图文详解 解决 MVC4 Code First 数据迁移

    在使用Code first生成数据库后 当数据库发生更改时 运行程序就会出现数据已更改的问题  这时可以删除数据库重新生成解决 但是之前的数据就无法保留  为了保留之前的数据库数据  我们需要使用到C ...

  9. mybatis动态sql——(六)

    0     什么是动态sql mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 通过mybatis提供的各种标签方法实现动态拼接sql.

  10. 转:存储之直连存储Dell Powervault MD 3000

    存储之直连存储DellPowervault MD 3000 存储根据服务器类型可以分为:封闭系统的存储和开放系统的存储 1.封闭系统的存储:封闭系统主要指大型机,AS400等服务器 2.开放系统的存储 ...