CodeForces 794 G.Replace All
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\) 的长度,方案数就是
\]
现在考虑 \('?'\) 的影响,令 \(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的更多相关文章
- [codeforces 549]G. Happy Line
[codeforces 549]G. Happy Line 试题描述 Do you like summer? Residents of Berland do. They especially love ...
- Codeforces 1207 G. Indie Album
Codeforces 1207 G. Indie Album 解题思路 离线下来用SAM或者AC自动机就是一个单点加子树求和,套个树状数组就好了,因为这个题广义SAM不能存在 \(len[u] = l ...
- codeforces 659 G. Fence Divercity 组合数学 dp
http://codeforces.com/problemset/problem/659/G 思路: f(i,0/1,0/1) 表示到了第i个,要被切的块开始了没有,结束了没有的状态的方案数 递推看代 ...
- Codeforces 803 G. Periodic RMQ Problem
题目链接:http://codeforces.com/problemset/problem/803/G 大致就是线段树动态开节点. 然后考虑到如果一个点还没有出现过,那么这个点显然未被修改,就将这个点 ...
- Codeforces 954 G. Castle Defense
http://codeforces.com/problemset/problem/954/G 二分答案 检验的时候,从前往后枚举,如果发现某个位置的防御力<二分的值,那么新加的位置肯定是越靠后越 ...
- Codeforces 746 G. New Roads
题目链接:http://codeforces.com/contest/746/problem/G mamaya,不知道YY了一个什么做法就这样过去了啊 2333 首先我显然可以随便构造出一棵树满足他所 ...
- Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS
G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组 ...
- codeforces 626 G. Raffles(线段树+思维+贪心)
题目链接:http://codeforces.com/contest/626/problem/G 题解:这题很明显买彩票肯定要买贡献最大的也就是说买p[i]*(num[i]+1)/(num[i]+a[ ...
- codeforces 794 C. Naming Company(贪心)
题目链接:http://codeforces.com/contest/794/problem/C 题意:有两个人每个人都有一个长度为n的字符串,两人轮流拿出一个字符串,放在一个长度为n的字符串的指定位 ...
随机推荐
- openstack项目【day23】:虚拟化介绍
本节内容 一 什么是虚拟化 二 为何要学习虚拟化 三 虚拟化技术主要分类(了解) 四 平台虚拟化技术又可以细分(了解) 一 什么是虚拟化 虚拟化说白了就是本来是一个完整的资源,切分或者说虚拟成多份,让 ...
- 前三章 man手册 查看文件
1 – 3章 1.1 man手册: 分1 - 9个区域,可以认为是一个一个小节 把man手册理解为一本书 第一节:可执行程序或shell命令 第二节:系统调用 第三节:库调用 第四节:特殊文件 第五节 ...
- Red Pen - 快速高效的获取设计项目的反馈
Red Pen 让设计师能够快速,高效的从你的同事和客户获取反馈.只需要简单的拖放图像到 Red Pen 主页,然后把生成的链接分享给你的同事或者客户.他们打开链接就能看到设计稿,并给予实时的反馈,所 ...
- 20155314 2016-2017-2 《Java程序设计》第8周学习总结
20155314 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 了解NIO 会使用Channel.Buffer与NIO2 会使用日志API.国际化 会使用正 ...
- [R语言]关联规则2---考虑items之间严格的时序关系
前面介绍了关联规则1---不考虑用户购买的items之间的时序关系,但在一些情况下用户购买item是有严格的次序关系了,比如在某些休闲游戏中,用户购买了道具A才能购买道具B,且道具A和B只能购买一次, ...
- js基础知识:闭包,事件处理,原型
闭包:其实就是js代码在执行的时候会创建变量对象的一个作用域链,标识符解析的时候会沿着作用域链一级一级的网上搜索,最后到达全局变量停止.所以某个函数可以访问外层的局部变量和全局变量,但是访问不了里层的 ...
- 转载 为什么print在Python 3中变成了函数?
转载自编程派http://codingpy.com/article/why-print-became-a-function-in-python-3/ 原作者:Brett Cannon 原文链接:htt ...
- Python内置模块与标准库
Python内置模块就是标准库(模块)吗?或者说Python的自带string模块是内置模块吗? 答案是:string不是内置模块,它是标准库.也就是说Python内置模块和标准库并不是同一种东西. ...
- 第八集:魔法阵 NTT求循环卷积
题目来源:http://www.fjutacm.com/Problem.jsp?pid=3283 题意:给两串长度为n的数组a和b,视为环,a和b可以在任意位置开始互相匹配得到这个函数的值,求这个函数 ...
- crontab每10秒钟执行一次
1.使用sleep 在crontab中加入 * * * * * sleep 10; /bin/date >>/tmp/date.txt* * * * * sleep 20; /bin/da ...