【CF809E】Surprise me! 树形DP 虚树 数学
来源:互联网 发布:2016淘宝运营推广方案 编辑:程序博客网 时间:2024/05/17 08:17
题目大意
给你一棵
题解
欧拉phi函数
然后直接反演统计就可以得到答案。
总的点数是
所以总的时间复杂度是
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<ctime>#include<utility>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> pii;ll p=1000000007;struct graph{ int h[200010]; int v[400010]; int w[400010]; int t[400010]; int n; graph() { memset(h,0,sizeof h); n=0; } void add(int x,int y,int z) { n++; v[n]=y; w[n]=z; t[n]=h[x]; h[x]=n; }};graph g,g2;int f[200010][20];int d[200010];int st[200010];int ti;void dfs(int x,int fa,int dep){ f[x][0]=fa; d[x]=dep; st[x]=++ti; int i; for(i=1;i<=19;i++) f[x][i]=f[f[x][i-1]][i-1]; for(i=g.h[x];i;i=g.t[i]) if(g.v[i]!=fa) dfs(g.v[i],x,dep+1);}int getlca(int x,int y){ if(d[x]<d[y]) swap(x,y); int i; for(i=19;i>=0;i--) if(d[f[x][i]]>=d[y]) x=f[x][i]; if(x==y) return x; for(i=19;i>=0;i--) if(f[x][i]!=f[y][i]) { x=f[x][i]; y=f[y][i]; } return f[x][0];}ll phi[200010];int b[200010];int pri[100010];int cnt;ll inv[200010];void init(int n){ int i,j; inv[0]=inv[1]=1; for(i=2;i<=n;i++) inv[i]=-(p/i)*inv[p%i]%p; phi[1]=1; cnt=0; for(i=2;i<=n;i++) { if(!b[i]) { pri[++cnt]=i; phi[i]=i-1; } for(j=1;j<=cnt&&i*pri[j]<=n;j++) { b[i*pri[j]]=1; if(i%pri[j]==0) { phi[i*pri[j]]=phi[i]*pri[j]; break; } phi[i*pri[j]]=phi[i]*phi[pri[j]]; } }}ll a[200010];ll s[200010];int c[200010];int c1[200010];int ct;int n;int stack[200010];int top;int cmp(int a,int b){ return st[a]<st[b];}ll s1[200010];ll s2[200010];ll sum;void add(int x,int y)//f[x]=y{ ll s3=(s1[x]+(d[x]-d[y])*s2[x])%p; sum=(sum+s3*s2[y]+s1[y]*s2[x])%p; s1[y]=(s1[y]+s3)%p; s2[y]=(s2[y]+s2[x])%p;}ll solve(int x){ sum=0; ct=top=0; int i; for(i=x;i<=n;i+=x) c1[++ct]=c[i]; sort(c1+1,c1+ct+1,cmp); int rt=getlca(c1[1],c1[ct]); if(rt!=c1[1]) { stack[++top]=rt; s1[rt]=s2[rt]=0; } for(i=1;i<=ct;i++) { if(i>=2) { int lca=getlca(c1[i],c1[i-1]); while(d[stack[top]]>d[lca]) if(d[stack[top-1]]<d[lca]) { s1[lca]=s2[lca]=0; add(stack[top],lca); stack[top]=lca; } else { add(stack[top],stack[top-1]); top--; } } stack[++top]=c1[i]; s1[c1[i]]=0; s2[c1[i]]=phi[a[c1[i]]]; } while(top>1) { add(stack[top],stack[top-1]); top--; } return sum*2%p;}int main(){ scanf("%d",&n); init(n); int i,x,y,j; for(i=1;i<=n;i++) { scanf("%lld",&a[i]); c[a[i]]=i; } for(i=1;i<n;i++) { scanf("%d%d",&x,&y); g.add(x,y,0); g.add(y,x,0); } dfs(1,0,1); for(i=1;i<=n;i++) s[i]=solve(i); ll ans=0; for(i=n;i>=1;i--) { for(j=i+i;j<=n;j+=i) s[i]-=s[j]; ans=(ans+s[i]*i%p*inv[phi[i]]%p)%p; } ans=ans*inv[n]%p*inv[n-1]%p; ans=(ans+p)%p; printf("%lld\n",ans); return 0;}
阅读全文
0 0
- 【CF809E】Surprise me! 树形DP 虚树 数学
- Puzzles (树形dp+组合数学)
- [Codeforces 809E] Surprise me! 莫比乌斯反演+虚树
- hdoj4705Y【树形dp+简单组合数学】
- 51Nod - 1677 树形dp + 组合数学
- 【XSY1602】安全网络 树形DP 数学
- hdu 4661 Message Passing(树形DP&组合数学)
- BZOJ 4013 HNOI2015 实验比较 树形DP+组合数学
- HDOJ题目4705 Y(简单树形DP+数学)
- Light OJ 1382 The Queue(树形DP+数学)
- 【bzoj4013】[HNOI2015]实验比较 树形dp+组合数学
- bzoj 4013: [HNOI2015]实验比较 (树形DP+组合数学)
- HDU 5909 Tree Cutting [树形dp+FWT]【动态规划+数学】
- [四校联训]切树游戏-树形DP-组合数学
- 周六日常训练,背包dp,树形dp,简单dp以及很多数学?
- bzoj2286 消耗战 虚树&树形dp
- bzoj2286 消耗战【虚树+树形dp】
- 树形dp
- 高性能Vs性价比,总有一款适合你,阿里云NAS家族深度解析
- 常用单词
- tortoisesvn安装
- 非root查看手机数据库和SharedPreferences的方法
- linked-list-cycle Java code
- 【CF809E】Surprise me! 树形DP 虚树 数学
- 电商体系的分级
- 语音识别完成诗句的查询功能,iOS AVSpeechSynthesis语音输出结果的诗歌APP
- 稀疏矩阵的转置
- python模块glob
- 【Selenium】select中下拉框内容选取的三种方法
- DRS.Technologies.Orca3D.v1.4.20170915.X64犀牛船舶设计
- others:南怀瑾先生讲:呵呼嘘吹嘻呬六字诀养生诀的要领---《南怀瑾与彼得圣吉》
- [Lintcode] #56 两数之和