ARC145做题笔记
A
清新结论题,可我被罚了两发(
很明显,操作改变不了第一个和最后一个字母,所以,如果第一个字母与最后一个字母,那这个字符串肯定最终可以回文。
因为是将相邻两个字母变成 AB,所以只要第一个字母是 B,那字符串最后也能变成回文。
注意:如果字符串只有两个字符,那么需要特判。
\(Code\)
#include <cstdio>
using namespace std;
#define N (int)(2e5+10)
char s[N];
int main(){
int n;
scanf("%d %s",&n,s+1);
bool flg=1;
if(s[1]=='A'){
for(int i=1;i<=n;++i){
if(s[i]!=s[n-i+1]) flg=0;
}
if(s[1]==s[n]) flg=1;
}
if(n==2&&s[1]!=s[n]) flg=0;
puts(flg?"Yes":"No");
return 0;
}
B
结论很明显,答案是
\[\sum_{i=a}^{n}[i \bmod a < b]
\]
这个式子如果是 \(1\) 到 \(n\) 的形式可以利用模的性质 \(O(1)\) 处理,然后容斥一下答案就做完了。
\(Code\)
#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long
ll n,a,b;
inline ll f(ll x){
return (x/a)*min(a,b)+min(x%a,b-1);
}
int main(){
scanf("%lld %lld %lld",&n,&a,&b);
printf("%lld",max(f(n)-f(a-1),0ll));
return 0;
}
C
看到排列直接想阶乘,考虑分个左右,猜了一波感觉和卡特兰数有点关系,好像可以直接暴力然后 OEIS 的
可以分成 \(n\) 对来使权值最大,总共有 \(n!\) 对配对,按照上文将配对分左右,那么合法数量是 \(\frac {\operatorname{C}_ {n}^{2n}}{n+1}\),也就是卡特兰数,有 \(2^n\) 种方法决定配对左元素,总的排列是 \(n!\) 个,所以答案是 \(2^n n! Cat_n\),也就是 \(2^n \frac{(2n)!}{(n+1)!}\)。
\(Code\)
#include <cstdio>
using namespace std;
#define int long long
#define mod 998244353
inline int fac(int n){
int res=1;
for(int i=2;i<=n;++i) res=res*i%mod;
return res;
}
inline int qpow(int a,int b){
int res=1;
while(b){
if(b&1) res=res*a%mod;
b>>=1;a=a*a%mod;
}
return res;
}
inline int C(int n,int m){
return fac(n)*qpow(fac(m+1)%mod,mod-2)%mod;
}
signed main(){
int n;
scanf("%lld",&n);
int ans=C(n<<1,n)*qpow(2,n)%mod;
printf("%lld",(ans+mod)%mod);
return 0;
}
D
题面复制下来太人性化了

浙公网安备 33010602011771号