什么垃圾比赛,A题说的什么鬼楞是没看懂。就我只会BD(其实C是个大水题二分),垃圾游戏,告辞,口胡了E就睡觉了。
等hacking结束再订正EFG吧,先贴一下BD的代码,AC两个垃圾题就不写了。
B
很容易发现,存在一种方案,使得相同字母连在一起,然后发现,当字母出现种类数大于等于4时,可以奇偶性相间地连接,然后讨论种类数<=3的:种类数为1,显然直接输出;种类数为2,若两字母相邻则无解,否则直接输出;种类数为3,若三字母相邻则无解,否则按照213/231(至少一种符合条件)输出。
#include<bits/stdc++.h> using namespace std; const int N=107; int T,n,m,ans,sum[N],id[N]; char s[N]; int main() { scanf("%d",&T); while(T--) { scanf("%s",s+1),n=strlen(s+1); memset(sum,0,sizeof sum); memset(id,0,sizeof id); for(int i=1;i<=n;i++)sum[s[i]-'a'+1]++; int num=0; for(int i=1;i<=26;i++)if(sum[i])id[i]=++num; if(num==1) { for(int i=1;i<=n;i++)printf("%c",s[i]); } else if(num>=4) { for(int i=26;i>=1;i--) if(id[i]&1) { for(int j=1;j<=sum[i];j++)printf("%c",'a'+i-1); } for(int i=26;i>=1;i--) if(id[i]&&id[i]%2==0) { for(int j=1;j<=sum[i];j++)printf("%c",'a'+i-1); } } else if(num==3) { int flag=0; for(int i=2;i<=25;i++)if(sum[i]&&sum[i-1]&&sum[i+1])flag=1; if(flag)printf("No answer"); else{ for(int i=2;i<=25;i++) for(int j=1;j<i;j++) for(int k=i+1;k<=26;k++) if(sum[j]&&sum[i]&&sum[k]) { for(int t=1;t<=sum[i];t++)printf("%c",'a'+i-1); if(j==i-1) { for(int t=1;t<=sum[k];t++)printf("%c",'a'+k-1); for(int t=1;t<=sum[j];t++)printf("%c",'a'+j-1); } else{ for(int t=1;t<=sum[j];t++)printf("%c",'a'+j-1); for(int t=1;t<=sum[k];t++)printf("%c",'a'+k-1); } } } } else{ int flag=0; for(int i=1;i<=25;i++)if(sum[i]&&sum[i+1])flag=1; if(flag)printf("No answer"); else{ for(int i=1;i<=26;i++)if(sum[i]) { for(int j=1;j<=sum[i];j++)printf("%c",'a'+i-1); } } } puts(""); } }
D
很容易想到一个DP,令f[i]表示以i为根的子树,从下面的节点走上来,最后一步是黑边的点数,g[i]表示全走白边的点数,于是就有f[u]=Σ(f[son]+g[son]+1),son为经过黑边的son,g[u]=Σ(g[son]+1),son为经过白边的son。然后这个东西很容易换根DP,根据黑白边讨论一下即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+7; int n,cnt,f[N],g[N],nf[N],ng[N],hd[N],v[N<<1],nxt[N<<1],w[N<<1]; ll ans; void adde(int x,int y,int z){v[++cnt]=y,nxt[cnt]=hd[x],w[cnt]=z,hd[x]=cnt;} void dfs(int u,int fa) { for(int i=hd[u];i;i=nxt[i]) if(v[i]!=fa) { dfs(v[i],u); if(!w[i])g[u]+=g[v[i]]+1; else f[u]+=f[v[i]]+g[v[i]]+1; } } void dfs2(int u,int fa) { ans+=nf[u]+ng[u]; for(int i=hd[u];i;i=nxt[i]) if(v[i]!=fa) { if(!w[i])nf[v[i]]=f[v[i]],ng[v[i]]=ng[u]; else nf[v[i]]=nf[u]-g[v[i]]+ng[u],ng[v[i]]=g[v[i]]; dfs2(v[i],u); } } int main() { scanf("%d",&n); for(int i=1,x,y,z;i<n;i++)scanf("%d%d%d",&x,&y,&z),adde(x,y,z),adde(y,x,z); dfs(1,0); nf[1]=f[1],ng[1]=g[1],dfs2(1,0); cout<<ans; }
E
口胡了一个做法,等hacking time结束再写。
FG
没来得及看