arc140 vp 记录
赛时 ABD,不足 zxy 水平的三分之一
A - Right String
直接枚举循环节,总数减去众数,随意判断即可。
B - Shorten ARC
要是 CF 的 B 也是这种风格,我大概永远也上不了 GM 了
可以转化为有若干个数,奇数步减一,偶数步归零,脑洞判断即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
const int mod=1e9+7;
#define inf 1e9
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
char S[maxn];
int n,m,a[maxn],top,Sum,res=1;
int main(){
n=read();scanf("%s",S+1);
for(int i=1;i<=n;i++)
if(S[i]=='R'&&S[i-1]=='A'&&S[i+1]=='C'){
a[++top]=1;int &v=a[top];
while(S[i-v-1]=='A'&&S[i+v+1]=='C')++v;
Sum+=v;
}
if(!top)return puts("0")&0;
sort(a+1,a+1+top);
for(int i=1,now=0,S1=0,S2=0;i<=top;i++){
if(a[i]>1)++now,S2+=a[i]-2;
else ++S1;Sum-=a[i];
int cnt=Sum+now+min(S1,S2);
if(cnt>i)res=i+i+1;
else if(cnt==i)res=i+i;
else break;
}printf("%d\n",res);
return 0;
}
C - ABS Permutation (LIS ver.)
实话说,还不会。
D - One to One
一开始有想过对代表元计数什么的,但由于这是个基环森林,我们考虑对环计数。
对于已有的环,首先加上它们的贡献。然后考虑若干棵树连出来的环。发现 \(T_1,T_2,\cdots,T_k\) 连出来的方案数为 \(\prod siz_{T_i}\),而这个方案数对应的系数就是只有一个置换环的方案数。所以我们把所有的树拿出来 \(dp\) 即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
const int mod=998244353;
#define inf 1e9
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
const int N=2005;
int n,m,dp[N],C[N][N],fac[N],a[N],cnt,F[N],siz[N],vis[N],pw[N],f[N][N],st[N],top,ans;
inline int find(int x){return x==F[x]?x:F[x]=find(F[x]);}
inline void merge(int x,int y){
x=find(x),y=find(y);
if(x==y)vis[x]=1;
else F[y]=x,siz[x]+=siz[y],vis[x]|=vis[y];
}
int main(){
n=read();C[0][0]=fac[0]=pw[0]=1;
for(int i=1;i<=n;i++){
C[i][0]=1;fac[i]=1ll*fac[i-1]*i%mod;
for(int j=1;j<=i;j++)
C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
dp[i]=fac[i];
for(int j=1;j<i;j++)
dp[i]=(dp[i]-1ll*dp[j]*C[i-1][j-1]%mod*fac[i-j])%mod;
}
for(int i=1;i<=n;i++)F[i]=i,siz[i]=1,pw[i]=1ll*pw[i-1]*n%mod;
for(int i=1,x;i<=n;i++){
x=read();
if(x==-1)++cnt;
else merge(i,x);
}
for(int i=1;i<=n;i++)
if(find(i)==i){
if(vis[i])ans=(ans+pw[cnt])%mod;
else st[++top]=siz[i];
}
f[0][0]=1;
for(int i=1;i<=top;i++)
for(int j=0;j<i;j++){
f[i][j]=(f[i][j]+1ll*f[i-1][j]*n)%mod;
f[i][j+1]=(f[i][j+1]+1ll*f[i-1][j]*st[i])%mod;
}
for(int i=1;i<=top;i++)
ans=(ans+1ll*f[top][i]*dp[i])%mod;
printf("%d\n",(ans+mod)%mod);
return 0;
}
E - Not Equal Rectangle
结论就是 \(A_{i,j}=\lfloor \frac{i}{23}\rfloor\lfloor \frac{j}{23}\rfloor +i+j\bmod 23\)
先说证明,再说想法。