洛谷P11487「Cfz Round 5」Gnirts 10
传送锚点
摸鱼环节
「Cfz Round 5」Gnirts 10
题目背景
English statement. You must submit your code at the Chinese version of the statement.
In Memory of \(\text{F}\rule{66.8px}{6.8px}\).
题目描述
题面还是简单一点好。
- 给定 \(n, m\),以及一个长为 \(n + m\) 的 \(\tt{01}\) 串 \(S\)。
- 对于 \(\tt 01\) 串 \(T\),定义 \(f(T)\) 为 \(S\) 的最长的前缀的长度,使得该前缀是 \(T\) 的子序列 \(^\dagger\)。
- 对于每个 恰包含 \(\bm n\) 个 \(\tt 1\) 和 \(\bm m\) 个 \(\tt 0\) 的 \(\tt{01}\) 串 \(T\),求 \(f(T)\) 的和。答案对 \(2933256077^\ddagger\) 取模。
\(\dagger\):请注意,子序列可以不连续。换句话说,\(a\) 是 \(b\) 的子序列,当且仅当在 \(b\) 中删去 \(\geq 0\) 个字符后,可以得到 \(a\)。注意,空串总是任何串的子序列。
\(\ddagger\):模数为质数。
输入格式
第一行包含两个整数 \(n, m\)。
第二行包含一个长度为 \(n + m\) 的 \(\tt 01\) 串 \(S\)。
输出格式
输出一行一个整数,表示答案对 \(2933256077\) 取模后的结果。
样例 #1
样例输入 #1
2 1
000
样例输出 #1
3
样例 #2
样例输入 #2
5 5
0010111011
样例输出 #2
1391
提示
「样例解释 #1」
所有可能的序列有且仅有公共序列 \(\texttt{0}\)。因为恰有 \(3\) 种不同的 \(T\)(\(\tt 110, 101, 011\)),所以答案为 \(1\times 3 = 3\)。
「数据范围」
对于所有测试数据,保证 \(1 \leq n, m \leq 3\times 10^6\)。
本题采用捆绑测试。
- Subtask 0(13 points):\(\max(n, m) \leq 5\)。
- Subtask 1(13 points):\(\max(n, m) \leq 100\)。
- Subtask 2(34 points):\(\max(n, m) \leq 3 \times 10^3\)。
- Subtask 3(40 points):无特殊限制。
大数学。
正片开始
考虑到我们只关心答案,而答案只需要 \(S\) 某种前缀的个数,并不需要考虑具体的方案,于是我们可以从前缀的方向考虑。
对于答案而言,首先答案对质数取模,其次每个合法的\(T\),可以看作是 \(n\) 个 \(1\) 和 \(m\) 个 \(0\) 的一种组合。于是得到暴力枚举每种组合计算答案的朴素算法,很显然,这只能搞到13分。
考虑对 \(S\) 的前缀一位位处理答案,对于一个 \(S\) 的前缀 \(k\) ,长度为 \(l\) ,其中有 \(cnt0\) 个 \(0\) , \(cnt1\) 个 \(1\) 。
假设第 \(l+1\) 位为 \(1\) ,那显然,剩下的 \(n-cnt1\) 个 \(1\) 只能插在第 \(l\) 位之前,不然会导致前缀变长。
也就是要把 \(n-cnt1\)个\(1\) 分散在 \(cnt0\) 个 \(0\) 之间,两个 \(0\) 之间可以没有1。
于是插入\(1\)的答案为 \(\dbinom{n-cnt1+cnt0-1}{cnt0-1}\) 同理, \(0\) 则是有 \(cnt1\) 块板,于是 \(0\) 的答案 \(\dbinom{m-cnt0+cnt1}{cnt1}\)。
一位的答案为:
$ans=\sum_{i=1}^{n+m} i\times g(i) $。
完整代码
#ifdef ONLINE_JUDGE
#else
#define Qiu_Cheng
#endif
#include <bits/stdc++.h>
#define int long long
using namespace std;
// typedef long long ll;
const int N=6e6+50,M=1e6,mod=2933256077;
int fac[N],ifac[N],inv[N];
int C(int a,int b)
{if(a==b) return 1;if(a<b||b<0) return 0;return fac[a]*ifac[a-b]%mod*ifac[b]%mod;
}
void YCL()
{fac[0]=1;inv[1]=1;ifac[0]=1;for(int i=1;i<=6e6;i++){fac[i]=fac[i-1]*i%mod;if(i>=2)inv[i]=(mod-mod/i)*inv[mod%i]%mod;ifac[i]=ifac[i-1]*inv[i]%mod;}
}
int n,m,len,ans=0;
string s;
inline void solve()
{ YCL();cin>>n>>m;len=n+m;cin>>s;s=' '+s;int cnt0=0,cnt1=0;for(int i=1;i<=len;i++){if(s[i]=='0')cnt0++;else cnt1++;ans=(ans+i*(s[i+1]=='0'?C(m-cnt0+cnt1-1,cnt1-1)*C(n-cnt1+cnt0,cnt0)%mod:C(n-cnt1+cnt0-1,cnt0-1)*C(m-cnt0+cnt1,cnt1)%mod))%mod;}cout<<ans<<endl;}
signed main()
{
#ifdef Qiu_Chengfreopen("1.in","r",stdin);freopen("1.out","w",stdout);
#endif// ios::sync_with_stdio(false);// cin.tie(0);// cout.tie(0);// int QwQ;// cin>>QwQ;// while(QwQ--)solve();solve();return 0;
}// 6666 66666 666666
// 6 6 6 6 6
// 6 6 6666 6
// 6 6 6 6 6
// 6666 6 6 6666666//g++ -O2 -std=c++14 -Wall "-Wl,--stack= 536870912 " cao.cpp -o cao.exe
完结收工!!!!!
个人主页
看完点赞,养成习惯
\(\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\)