Codeforces Round#630 div2
B题
https://codeforces.ml/problemset/problem/1332/B
第一感觉使DUS似乎不对结果C题还真出了个DUS
然后又感觉是两个数有公因数则可以连边然后跑环?
emmm最后发现因为输出可满足的答案即可
所以就可以枚举因数,只要有这个因数的数都可以算一个颜色
如果一个数有多个因数,随便分配它(题目答案要求很宽松)
#include<bits/stdc++.h> using namespace std; const int N=1e4+2; int T,n,x,k,col[N]; vector <int> ans[N]; int main() { scanf("%d",&T); while(T--) { memset(col,0,sizeof(col)); k=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&x); for(int j=2;j<=x;j++) { if(x%j==0) { ans[j].emplace_back(i); break; } } } for(int i=1;i<=N;i++) { if(ans[i].size()!=0) { k++; for(auto j:ans[i]) { col[j]=k; } } } printf("%d\n",k); for(int i=1;i<=n;i++) printf("%d ",col[i]); printf("\n"); for(int i=1;i<=N;i++) ans[i].clear(); } }
C题
https://codeforces.ml/problemset/problem/1332/C
就是每个点i与i+k权值要相同,与n-i+1也要相同,问最小改几个点的权值使条件满足,开始还想着先连边在并查集,结果发现直接并查集就行了
emmm...又被卡memset了,再也不用了
应该算模板题吧
#include<bits/stdc++.h> using namespace std; const int N=2e5+2; int T,n,k,ans,fa[N],tot[N][30],maxn[N],c[N],deep[N]; char x; int find(int x) { if(fa[x]==x) return x; return fa[x]=find(fa[x]); } int main() { scanf("%d",&T); while(T--) { ans=0; scanf("%d %d",&n,&k); getchar(); ans=0; for(int i=0;i<=n;i++) { for(int j=0;j<30;j++) { tot[i][j]=0; } } for(int i=0;i<n;i++) { scanf("%c",&x); c[i]=x-'a'; } for(int i=0;i<n;i++) { fa[i]=i; tot[i][c[i]]=1;//每个颜色的个数 maxn[i]=1;//最多的同种颜色个数 deep[i]=1;//以i为根子节点的个数 } for(int i=0;i<n;i++) { int r1=find(fa[i%k]),r2=find(fa[i]); if(r1!=r2) { fa[r2]=r1; deep[r1]+=deep[r2]; for(int j=0;j<=26;j++) { tot[r1][j]+=tot[r2][j]; maxn[r1]=max(tot[r1][j],maxn[r1]); } } } for(int i=0;i<n;i++) { int r1=find(fa[i]),r3=find(fa[n-i-1]); if(r1!=r3) { fa[r3]=r1; deep[r1]+=deep[r3]; for(int j=0;j<=26;j++) { tot[r1][j]+=tot[r3][j]; maxn[r1]=max(tot[r1][j],maxn[r1]); } } } for(int i=0;i<n;i++) { if(fa[i]==i) ans+=deep[i]-maxn[i]; } printf("%d\n",ans); } } /* 1 36 9 hippopotomonstrosesquippedaliophobia */
D题
https://codeforces.ml/contest/1332/problem/D
emm坑估计是填不了了|flag!
$道路千万条,点赞第一条;阅读不规范,笔者两行泪$