计蒜客 青云的机房组网方案
来源:互联网 发布:行测怎么提高常识 知乎 编辑:程序博客网 时间:2024/04/30 03:46
含
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define rep(x,st,en) for(int x=st;x<=en;x++)#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int M=100005;const int Num=100000;typedef long long ll;int nxt[M][18],bin[20];int dep[M];struct Edge{ int to,nxt;}edge[M<<2];//虚树中的边可以利用深度O(1)获得 int last[M];int head[M];int prv,allc;int mul[M];int id[M],n;ll ans,val;void ins(int u,int v){ edge[++allc]=(Edge){v,last[u]}; last[u]=allc;}void ins_(int u,int v){ edge[++allc]=(Edge){v,head[u]}; head[u]=allc;}bool cmp(int x,int y){ return id[x]<id[y];}int a[M+5];int tot,top,dfs_clock;int lca(int u,int v){ if(dep[u]<dep[v])swap(u,v); int d=dep[u]-dep[v]; for(int i=0;i<18;i++) if(bin[i]&d) u=nxt[u][i]; if(u==v)return u; for(int i=17;i>=0;i--) if(nxt[u][i]!=nxt[v][i]){ u=nxt[u][i]; v=nxt[v][i]; } return nxt[u][0];}int stk[M];int sz[M];void dfs1(int x,int f){ for(int i=last[x];i;i=edge[i].nxt){ int y=edge[i].to; if(y!=f){ dfs1(y,x); sz[x]+=sz[y]; } } if(f)val+=1ll*abs(dep[x]-dep[f])*sz[x]*(tot-sz[x]);}void clear(int x,int f){ for(int i=last[x];i;i=edge[i].nxt){ int y=edge[i].to; if(y!=f)clear(y,x); } last[x]=sz[x]=0;}void solve(int K){ tot=top=0; for(int i=K;i<=Num;i+=K) for(int j=head[i];j;j=edge[j].nxt) a[tot++]=edge[j].to; if(tot<=1)return; val=0; allc=prv; sort(a,a+tot,cmp); for(int i=0;i<tot;i++)sz[a[i]]=1; for(int i=0;i<tot;i++){ int f=0,s=a[i]; while(top>0){ f=lca(stk[top],s); if(top>1&&dep[f]<dep[stk[top-1]]){ ins(stk[top],stk[top-1]); ins(stk[top-1],stk[top]); top--; } else if(dep[f]<dep[stk[top]]){ ins(stk[top],f); ins(f,stk[top]); top--; break; } else break; } if(stk[top]!=f)stk[++top]=f; stk[++top]=s; } while(top>1){ ins(stk[top],stk[top-1]); ins(stk[top-1],stk[top]); top--; } dfs1(a[0],0); ans+=val*mul[K]; clear(a[0],0);// printf("%I64d\n",val);}void dfs(int x,int f){ id[x]=++dfs_clock; nxt[x][0]=f; dep[x]=dep[f]+1; for(int i=0;nxt[x][i];i++) nxt[x][i+1]=nxt[nxt[x][i]][i]; for(int i=last[x];i;i=edge[i].nxt){ int y=edge[i].to; if(y!=f)dfs(y,x); }}char mark[M];int prm[M];void pre(){ int cnt=0; mul[1]=1; for(int i=2;i<=Num;i++){ if(!mark[i]){ prm[cnt++]=i; mul[i]=-1; } for(int j=0;j<cnt&&i*prm[j]<=Num;j++){ mark[i*prm[j]]=true; if(i%prm[j]==0){ mul[i*prm[j]]=0; break; } else mul[i*prm[j]]=-mul[i]; } }}int main(){ scanf("%d",&n); pre(); for(int i=0;i<20;i++)bin[i]=1<<i; for(int v,i=1;i<=n;i++){ scanf("%d",&v); ins_(v,i); } prv=allc; for(int u,v,i=1;i<n;i++){ scanf("%d%d",&u,&v); ins(u,v);ins(v,u); } //这里的边得到dfs序和深度以后就用不到了 dfs_clock=0; dfs(1,0); ans=0; for(int i=1;i<=n;i++) last[i]=0; for(int i=1;i<=Num;i++) if(mul[i])solve(i); cout<<ans<<endl; return 0;}
0 0
- 计蒜客 青云的机房组网方案
- 计蒜客 青云的机房组网方案
- 计蒜客 青云的机房组网方案(简单)floyd
- 青云的机房组网方案(简单)
- 青云的机房组网方案(简单)-Java
- 2016计蒜客初赛第一场 青云的机房组网方案(困难):图论+虚树+容斥
- 2016 计蒜之道 初赛 第一场 青云的机房组网方案(中等)
- 2016 计蒜之道 初赛 第一场 青云的机房组网方案(简单)
- 计蒜之道 青云的机房组网方案(中等)
- 2016计蒜之道初赛第一场--B青云的机房组网方案(简单)【floyd】
- 基于CSD的WAP组网方案
- 【计蒜客11216】青云的网络设计方案 题解
- 无线AP组网方案
- 无线AP组网方案
- 小型办公组网方案
- GPRS组网方案
- TCP组网方案
- GPRS组网方案
- private,static,final和域对于重写覆盖方法的区别。
- Android 退出应用
- Android 组件动态设置宽高
- 关于使用Xcode自带的单元测试UnitTest的介绍
- 使用android stdio1.5进行junit测试
- 计蒜客 青云的机房组网方案
- 英语单词最常用的328个前缀后缀(超全面)
- centos6.5安装mysql5.6
- stuts、hibernate、spring
- SpringMVC 乱码
- Apache Spark 的一些浅见。
- 生成验证码
- 使用ruby的gem安装gem包的SSL证书错误
- Unable to locate package错误解决