题解:P10066 [CCO 2023] Binaria
wjbbssb250 · · 题解
Solution
一道考察差分约束与组合计数的题。
设原二进制字符串为
考虑相邻两个窗口的和:
因为
- 若
A_{i+1}-A_i = 1 ,则必有b_{i+K}=1,\; b_i=0 ; - 若
A_{i+1}-A_i = -1 ,则必有b_{i+K}=0,\; b_i=1 ; - 若
A_{i+1}-A_i = 0 ,则b_{i+K} = b_i ,两者必须相等。
对于相等关系,用并查集维护,同时在合并时优先让已知值的集合作为代表。这样处理完所有
注意到,滑动窗口的递推式
设前
模数
总时间复杂度
::::info[Code]
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MOD = 1e6 + 3;
int n,k,a[MOD],b[MOD],jc[MOD],fa[MOD],cnt;
int _find(int x){
if(x == fa[x])
return x;
return fa[x] = _find(fa[x]);
}
int qpow(int x,int y){
int res = 1;
while(y){
if(y & 1)
res = res * x % MOD;
x = x * x % MOD;
y >>= 1;
}
return res;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin >> n >> k;
jc[0] = 1;
for(int i = 1;i <= k;i++)
jc[i] = jc[i - 1] * i % MOD;
for(int i = 1;i <= n;i++)
fa[i] = i,b[i] = -1;
cin >> a[1];
for(int i = 2;i <= n - k + 1;i++){
cin >> a[i];
cnt = a[i] - a[i - 1];
if(cnt == 1)
b[i + k - 1] = 1,b[i - 1] = 0;
else if(cnt == -1)
b[i + k - 1] = 0,b[i - 1] = 1;
else{
int x = _find(i - 1);
int y = _find(i + k - 1);
if(b[x] != -1)
fa[y] = x;
else
fa[x] = y;
}
}
cnt = 0;
for(int i = 1;i <= k;i++)
if(b[_find(i)] == -1)
cnt++;
for(int i = 1;i <= k;i++)
if(b[_find(i)] == 1)
a[1]--;
cout << jc[cnt] * qpow(jc[a[1]],MOD - 2) % MOD * qpow(jc[cnt - a[1]],MOD - 2) % MOD << '\n';
return 0;
}
::::