A:设f[i][j][0/1]为前i个数第i位为j且第i位未满足/已满足限制的方案数。大力dp前缀和优化即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; 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^48),c=getchar(); return x*f; } #define N 100010 #define P 998244353 #define K 200 int n,a[N],f[N][K+1][2],g[N][K+1][2];//0 there is limit void inc(int &x,int y){x+=y;if (x>=P) x-=P;} int main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif n=read(); for (int i=1;i<=n;i++) a[i]=read(); f[0][0][0]=1; for (int i=0;i<=K;i++) g[0][i][0]=1; for (int i=1;i<=n;i++) { if (a[i]!=-1) { inc(f[i][a[i]][1],(g[i-1][K][1]-g[i-1][a[i]-1][1]+P)%P); inc(f[i][a[i]][1],f[i-1][a[i]][0]); inc(f[i][a[i]][0],g[i-1][a[i]-1][0]),inc(f[i][a[i]][0],g[i-1][a[i]-1][1]); } else { for (int j=1;j<=K;j++) { inc(f[i][j][1],(g[i-1][K][1]-g[i-1][j-1][1]+P)%P); inc(f[i][j][1],f[i-1][j][0]); inc(f[i][j][0],g[i-1][j-1][0]),inc(f[i][j][0],g[i-1][j-1][1]); } } for (int j=1;j<=K;j++) g[i][j][0]=(f[i][j][0]+g[i][j-1][0])%P,g[i][j][1]=(f[i][j][1]+g[i][j-1][1])%P; } if (a[n]!=-1) cout<<f[n][a[n]][1]; else { int ans=0; for (int i=1;i<=200;i++) inc(ans,f[n][i][1]); cout<<ans; } return 0; }
B:显然若合法根一定是直径中点。跑几遍dfs。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; 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^48),c=getchar(); return x*f; } #define N 100010 int n,m,p[N],deep[N],fa[N],t=0,root; struct data{int to,nxt; }edge[N<<1]; void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;} void dfs(int k) { for (int i=p[k];i;i=edge[i].nxt) if (edge[i].to!=fa[k]) { deep[edge[i].to]=deep[k]+1; fa[edge[i].to]=k; dfs(edge[i].to); } } bool check(int k) { bool flag=1; int x=0; for (int i=p[k];i;i=edge[i].nxt) if (edge[i].to!=fa[k]) x++; if (x==0) return deep[k]==m; if (x>=3) { for (int i=p[k];i;i=edge[i].nxt) if (edge[i].to!=fa[k]) flag=flag&&check(edge[i].to); } else flag=0; return flag; } int main() { #ifndef ONLINE_JUDGE freopen("b.in","r",stdin); freopen("b.out","w",stdout); #endif n=read(),m=read(); for (int i=1;i<n;i++) { int x=read(),y=read(); addedge(x,y),addedge(y,x); } dfs(1); for (int i=1;i<=n;i++) if (deep[i]>=deep[root]) root=i; memset(deep,0,sizeof(deep)); memset(fa,0,sizeof(fa)); dfs(root); for (int i=1;i<=n;i++) if (deep[i]>=deep[root]) root=i; if (deep[root]!=m*2) {cout<<"No";return 0;} for (int i=1;i<=m;i++) root=fa[root]; memset(deep,0,sizeof(deep)); memset(fa,0,sizeof(fa)); dfs(root); if (check(root)) cout<<"Yes"; else cout<<"No"; return 0; }
一题20min感觉非常友好。然后一看C是构造就弃了。D一点不会。E看不懂。hack不动。一个多小时无所事事地看着排名往下掉。
难得手速快了一次?
result:rank 95 rating +83 突然就上黄了感觉下一场就掉回去了啊。