Codeforces Round 411 Div.2 题解
Posted SiriusRen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round 411 Div.2 题解相关的知识,希望对你有一定的参考价值。
A Fake NP standard input/output 1 s, 256 MB Submit Add to favourites x3673 B 3-palindrome standard input/output 1 s, 256 MB Submit Add to favourites x3760 C Find Amir standard input/output 1 s, 256 MB Submit Add to favourites x3503 D Minimum number of steps standard input/output 1 s, 256 MB Submit Add to favourites x2242 E Ice cream coloring standard input/output 2 s, 256 MB Submit Add to favourites x142 F Expected diameter of a tree standard input/output 3 s, 256 MB Submit Add to favourites x28
考的时候写出来了前4道... ORZ yzy Rank7
A题
考的时候SB 了 r-l<=100的时候搞了个暴力判了判..
应该是这样的..
//By SiriusRen #include <map> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; map<int,int>mp,remp; int l,r; int main(){ scanf("%d%d",&l,&r); if(l==r){ printf("%d\n",l); } else{ puts("2"); } }
B 构造 aabbaabb...
//By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n,a[200050]; int main(){ scanf("%d",&n); a[1]=0,a[2]=1; for(int i=3;i<=n;i++){ if(a[i-2]==0)a[i]=1; else a[i]=0; } for(int i=1;i<=n;i++)printf("%c",a[i]+‘a‘); }
C 贪心 1->n->2->n-1.....
判一下奇偶
//By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n; int main(){ scanf("%d",&n); printf("%d\n",n/2-1+(n%2)); }
D 乱搞
//By SiriusRen #include <cstdio> #include <cstring> using namespace std; const int N=1000050,p=1000000007; char s[N]; int n,ans,res; int main(){ scanf("%s",s+1),n=strlen(s+1); for(int i=n;i;i--) if(s[i]==‘b‘)res=(res+1)%p; else (ans+=res)%=p,(res+=res)%=p; printf("%d\n",ans); }
E max(s[i]) 贪心染色 别问我为什么
//By SiriusRen #include<bits/stdc++.h> #define N 300005 using namespace std; vector<int> G[N],E[N]; int n,m,ans,col[N],cnt,vis[N]; void dfs(int t,int fa){ int i,cnt=1; for(i=0;i<E[t].size();i++) if(col[E[t][i]]) vis[col[E[t][i]]]=t; for(i=0;i<E[t].size();i++) if(!col[E[t][i]]){ while(vis[cnt]==t) cnt++; vis[cnt]=t,col[E[t][i]]=cnt; } for(i=0;i<G[t].size();i++) if(G[t][i]!=fa)dfs(G[t][i],t); } int main() { int i,x,y; scanf("%d %d",&n,&m); for(i=1;i<=n;i++){ scanf("%d",&x),ans=max(ans,x); while(x--)scanf("%d",&y),E[i].push_back(y); } for(i=1;i<n;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x); dfs(1,0); printf("%d\n",max(ans,1)); for(i=1;i<=m;i++)printf("%d ",max(col[i],1)); return 0; }
F
保存每个点能走的最远距离 (可以O(1)求)
搞个前缀和之类的东西维护一下
每回 O(小块)的复杂度 再开个set记录一下答案 就(卡)过去了..
//By SiriusRen #include <set> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=200050; vector<int>vec[N],dis[N],sum[N]; struct Node{int x,y;double ans;}JY; bool operator<(Node a,Node b){if(a.x!=b.x)return a.x<b.x;return a.y<b.y;} set<Node>s;set<Node>::iterator it; int n,m,q,first[N],nxt[N],v[N],w[N],tot,root,xx,yy,vis[N]; int maxx[N][2],rec[N][2],f[N],Root[N],vv[N],fi,flag,size[N]; void add(int x,int y){w[tot]=1,v[tot]=y,nxt[tot]=first[x],first[x]=tot++;} int find(int x){return x==f[x]?x:f[x]=find(f[x]);} void get_dia(int x,int fa){ rec[x][0]=rec[x][1]=x; for(int i=first[x];~i;i=nxt[i])if(v[i]!=fa){ get_dia(v[i],x); if(maxx[v[i]][0]+w[i]>maxx[x][0]) maxx[x][1]=maxx[x][0],rec[x][1]=rec[x][0], maxx[x][0]=maxx[v[i]][0]+w[i],rec[x][0]=rec[v[i]][0]; else if(maxx[v[i]][0]+w[i]>maxx[x][1]) maxx[x][1]=maxx[v[i]][0]+w[i],rec[x][1]=rec[v[i]][0]; }if(maxx[x][0]+maxx[x][1]>maxx[root][0]+maxx[root][1])root=x; } void DFS(int x,int fa,int deep){ vv[x]=max(vv[x],deep); if(flag)vec[fi].push_back(vv[x]),size[fi]++; for(int i=first[x];~i;i=nxt[i])if(v[i]!=fa){ DFS(v[i],x,deep+w[i]); } } int main(){ memset(first,-1,sizeof(first)); scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=n;i++)f[i]=i; for(int i=1;i<=m;i++) scanf("%d%d",&xx,&yy),add(xx,yy),add(yy,xx),f[find(xx)]=find(yy); for(int i=1;i<=n;i++){ fi=find(i); if(!rec[fi][0]){ root=flag=0,get_dia(i,0),Root[fi]=root; DFS(rec[root][0],0,0),flag=1,DFS(rec[root][1],0,0); } } for(int i=1;i<=n;i++){ fi=find(i); if(!vis[fi]){ vis[fi]=1; dis[fi].resize(size[fi]+1),sum[fi].resize(size[fi]+1); for(int j=0;j<vec[fi].size();j++) dis[fi][vec[fi][j]]++,sum[fi][vec[fi][j]]+=vec[fi][j]; for(int j=size[fi]-1;j>=0;j--) dis[fi][j]+=dis[fi][j+1],sum[fi][j]+=sum[fi][j+1]; } } while(q--){ scanf("%d%d",&xx,&yy); int fx=find(xx),fy=find(yy); if(fx==fy){puts("-1");continue;} if(vec[fx].size()>vec[fy].size())swap(xx,yy),swap(fx,fy); JY.x=fx,JY.y=fy; if((it=s.find(JY))!=s.end()){printf("%.10lf\n",it->ans);continue;} int dis1=maxx[Root[fx]][0]+maxx[Root[fx]][1]; int dis2=maxx[Root[fy]][0]+maxx[Root[fy]][1]; int Dis=max(dis1,dis2); long long ans=0; for(int i=0;i<vec[fx].size();i++){ ans+=sum[fy][Dis-vec[fx][i]]+1ll*dis[fy][Dis-vec[fx][i]]*(vec[fx][i]+1); ans+=1ll*Dis*(size[fy]-dis[fy][Dis-vec[fx][i]]); } JY.ans=(double)ans/size[fx]/size[fy],s.insert(JY); printf("%.10lf\n",(double)ans/size[fx]/size[fy]); } // for(int i=1;i<=n;i++)printf("%d ",vv[i]); }
以上是关于Codeforces Round 411 Div.2 题解的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #411 (Div. 2)
Codeforces Round #411 (Div. 2)C. Find Amir(想法题)
Codeforces Round #411 (Div. 2)D. Minimum number of steps(贪心)
Codeforces Round#722 div.1+div.2题解