题解:P10066 [CCO 2023] Binaria
模拟赛题,简单题。
看到大部分题解都比我的写法稍微复杂一点,补一发题解。
可以发现每当 SMS 序列第
但当SMS序列第
我们只需根据这三条规则将原序列尽可能填满,我们就会发现一个神秘的事情,原序列每 其实只要多手玩几组样例就行
根据这个结论,我们只需算原序列前
时间复杂度
code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e6 + 5,mod = 1e6 + 3;
int n,k,fac[maxn],inv[maxn],a[maxn],b[maxn],num1[maxn],num0[maxn];
inline int qpow(int a,int b)
{
int res = 1;
while(b)
{
if(b & 1)
{
res = res * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return res % mod;
}
inline void init()
{
fac[0] = 1;
for(int i = 1;i < maxn;i++)
{
fac[i] = (fac[i - 1] * i % mod);
}
return ;
}
inline int C(int n,int m)
{
if(n > m)
return -1;
else
return (fac[m] * qpow(fac[n],mod - 2) % mod * qpow(fac[m - n],mod - 2)) % mod;
}
bool vis[maxn];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
init();
cin >> n >> k;
memset(b,-1,sizeof(b));
int m = n - k + 1;
for(int i = 1;i <= m;i++)
{
cin >> a[i];
}
for(int i = 1;i < m;i++)
{
if(a[i] < a[i + 1])
{
b[i] = 0;
b[i + k] = 1;
}
else if(a[i] > a[i + 1])
{
b[i] = 1;
b[i + k] = 0;
}
}
for(int i = 1;i < m;i++)
{
if(b[i] != -1 && a[i] == a[i + 1])
{
b[i + k] = b[i];
}
}
for(int i = m;i > 1;i--)
{
if(b[i] != -1 && b[i - k] == -1)
{
b[i - k] = b[i];
}
}
int cnt1 = 0,cnt0 = 0;
for(int i = 1;i <= k;i++)
{
if(b[i] == 0)
cnt0++;
else if(b[i] == 1)
cnt1++;
}
cout << C(a[1] - cnt1,k - cnt0 - cnt1) << "\n";
/*
for(int i = 1;i <= n;i++)
{
cout << b[i] << " ";
}
cout << "\n";
*/
return 0;
}
/*
7 4
3 2 2 2
*/