秀秀的森林(forest)

题目要求树上两条不相交的链,且要求权值的和最大

性质:

1.如果某棵树上的最长链端点为x,y,则该树上任意一点z出发的最长链为max(xz,zy)

2如果两个点被连进了树里,那么他们的lca也一定被连进了树里、

有了这个,合并就很好做了

假设合并A,B两棵树,最长链端点为ax,ay ,bx,by

比较两两相连的答案取max即可

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 100005
#define ll long long
#define mod 1000000007
using namespace std;
int n,head[maxn],s[maxn],id[maxn],f[maxn][21],t1,t2,tot=1;
int x[maxn],y[maxn],v[maxn],ans,f1,f2,be[maxn];
int deep[maxn],d[maxn];
ll A[maxn];
struct node{
int v,nex;
}e[maxn*2];
void lj(int t1,int t2){
e[++tot].v=t2;e[tot].nex=head[t1];head[t1]=tot;
}
void dfs(int k,int fa){
f[k][0]=fa;deep[k]=deep[fa]+1;d[k]=d[fa]+s[k];
for(int i=head[k];i;i=e[i].nex){
if(e[i].v!=fa)dfs(e[i].v,k);
}
}
int getf(int k){
if(be[k]==k)return k;
be[k]=getf(be[k]);return be[k];
}
int Lca(int a,int b){
if(deep[a]<deep[b])swap(a,b); for(int x=20;x>=0;x--)if(deep[f[a][x]]>=deep[b])a=f[a][x];
for(int x=20;x>=0;x--)if(f[a][x]!=f[b][x])a=f[a][x],b=f[b][x]; if(a==b)return a;
else return f[a][0];
}
int Len(int a,int b){
int lca=Lca(a,b);
return d[a]+d[b]-d[lca]-d[f[lca][0]];
}
ll work(int k,int num){
ll ss=1,p=k;
while(num){
if(num&1)ss=ss*p;
p=p*p;p%=mod;ss=ss%mod;num>>=1;
}
return ss;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)scanf("%d",&s[i]);
for(int i=1;i<n;i++){
scanf("%d%d",&t1,&t2);
lj(t1,t2);lj(t2,t1);
}
for(int i=1;i<n;i++)scanf("%d",&id[i]);
dfs(1,0);
for(int j=1;j<=20;j++)
for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1];
ll ans=1;
for(int i=1;i<=n;i++){
x[i]=y[i]=i;v[i]=s[i];ans=ans*s[i]%mod;
be[i]=i;
}
A[n]=ans;
for(int num=n-1;num>=1;num--){
int t1=e[id[num]*2].v,t2=e[id[num]*2+1].v;
if(f[t1][0]!=t2)swap(t1,t2);
f1=getf(t1);f2=getf(t2);be[f1]=f2;
int ax=x[f1],ay=y[f1],bx=x[f2],by=y[f2];
int ansx,ansy,ansv,T;
if(v[f1]>v[f2])ansv=v[f1],ansx=ax,ansy=ay;
else ansv=v[f2],ansx=bx,ansy=by;
T=Len(ax,bx);if(T>ansv)ansv=T,ansx=ax,ansy=bx;
T=Len(ax,by);if(T>ansv)ansv=T,ansx=ax,ansy=by;
T=Len(ay,bx);if(T>ansv)ansv=T,ansx=ay,ansy=bx;
T=Len(ay,by);if(T>ansv)ansv=T,ansx=ay,ansy=by;
ans=ans*work(v[f1],mod-2)%mod*work(v[f2],mod-2)%mod;
v[f2]=ansv;x[f2]=ansx,y[f2]=ansy;
//cout<<ansx<<' '<<ansy<<' '<<ansv<<' '<<Lca(ansx,ansy)<<endl;
ans=ans*ansv%mod;A[num]=ans;
//cout<<ans<<' '<<ansv<<endl;
}
for(int i=1;i<=n;i++)printf("%lld\n",A[i]);
return 0;
}

秀秀的森林(forest)的更多相关文章

  1. 【题解】10-19秀秀的森林(forest)

    我恨秀秀倍增LCA+离线 (时光倒流) 题目 秀秀有一棵带n个顶点的树T,每个节点有一个点权ai-.有一天,她想拥有两棵树,于是她从T中删去了一条边.第二天,她认为三棵树或许会更好一些.因此,她又从她 ...

  2. [Python]Codecombat攻略之远边的森林Forest(1-40关)

    首页:https://cn.codecombat.com/play语言:Python 第二界面:远边的森林Forest(40关)时间:2-6小时内容:if/else.关系操作符.对象属性.处理输入网页 ...

  3. [Python] Codecombat攻略 远边的森林 Forest (1-40关)

    首页:https://cn.codecombat.com/play语言:Python 第二界面:远边的森林Forest(40关)时间:2-6小时内容:if/else.关系操作符.对象属性.处理输入网页 ...

  4. 2017-10-18 NOIP模拟赛

    纸牌游戏 #include<iostream> #include<cstdio> #include<ctime> #include<cstdlib> # ...

  5. Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结

    Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...

  6. kaggle之泰坦尼克的沉没

    Titanic 沉没 参见:https://github.com/lijingpeng/kaggle 这是一个分类任务,特征包含离散特征和连续特征,数据如下:Kaggle地址.目标是根据数据特征预测一 ...

  7. 【C#数据结构系列】树和二叉树

    线性结构中的数据元素是一对一的关系,树形结构是一对多的非线性结构,非常类似于自然界中的树,数据元素之间既有分支关系,又有层次关系.树形结构在现实世界中广泛存在,如家族的家谱.一个单位的行政机构组织等都 ...

  8. 【数据结构与算法】002—树与二叉树(Python)

    概念 树 树是一类重要的非线性数据结构,是以分支关系定义的层次结构 定义: 树(tree)是n(n>0)个结点的有限集T,其中: 有且仅有一个特定的结点,称为树的根(root) 当n>1时 ...

  9. NOIP2018提高组模拟题(五)

    字符串(string) Description 小林与亮亮正在做一个游戏.小林随意地写出一个字符串,字符串只由大写 字母组成,然后指定一个非负整数 m,亮亮可以进行至多 m 次操作,每次操作 为交换相 ...

随机推荐

  1. 在C++类中使用dllimport和dllexport导出,

    在Windows平台下: 您可以使用dllimport或dllexport属性声明C ++类.这些形式意味着导入或导出整个类.以这种方式导出的类称为可导出类. 以下示例定义可导出的类.导出其所有成员函 ...

  2. 支持无限加载的js图片画廊插件

    natural-gallery-js是一款支持无限加载的js图片画廊插件.该js图片画廊支持图片的懒加载,可以对图片进行搜索,分类,还可以以轮播图的方式来展示和切换图片. 使用方法 在页面中引入下面的 ...

  3. API调用微信getWXACodeUnlimit()获取小程序码

    微信文档地址:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/qr-code/getWXACodeUnlimit.html? ...

  4. Oracle数据库学习(一)

    Oracle数据库由甲骨文公司开发,是基于对象的关系型数据库:下面是简单的学习数据库操作等知识. 1.SQL单表查询(设一个表名为tab) (1)查询所有记录 select * from tab(一般 ...

  5. 手写promise

    写在前面: 在目前的前端分开中,我们对于异步方法的使用越来越频繁,那么如果处理异步方法的返回结果,如果优雅的进行异步处理对于一个合格的前端开发者而言就显得尤为重要,其中在面试中被问道最多的就是对Pro ...

  6. MySql主从同步笔记

    1.MySql主从同步是基于二进制日志实现的,二进制日志记录了主服务器数据库的所有变动,从服务器通过读取和执行该日志文件保持和主数据库的数据一致: 2.配置主服务器 a.开启二进制日志,找到MySql ...

  7. 如何使用koa实现socket.io官网的例子

    socket.io官网中使用express实现了一个最简单的IM即时聊天,今天我们使用koa来实现一下 ### 框架准备 确保你本地已经安装好了nodejs和npm,使用koa要求node版本> ...

  8. 【css】如何实现响应式布局

    “自适应网页设计”到底是怎么做到的?其实并不难. 首先,在网页代码的头部,加入一行viewport元标签. <meta name="viewport" content=&qu ...

  9. linux 基本指令 归类

    今天 我们来学习一下 最最基础的linux 指令,在我看来 linux的操作就是 增 删 改 查 这四个字. 1 查询 操作用户 woami 2查询登录用户 who am i 2 pwd //查询当前 ...

  10. 二叉树(dfs)

    样例输入: 5        //下面n行每行有两个数 2 3    //第i行的两个数,代表编号为i的节点所连接的两个左右儿子的编号. 4 5 0 0    // 0 表示无 0 0 0 0   样 ...