5286. 【NOIP2017提高A组模拟8.16】花花的森林 (Standard IO)

Time Limits: 1000 ms Memory Limits: 131072 KB

Description

Input

Output

Sample Input

3

1 2 3

1 2

1 3

2

1

Sample Output

6

9

6

Data Constraint

Hint

题解

我们考虑倒着做,即最开始是一个包含了 n 棵只有一个点的树的森林,然后不断加边,最后得到一棵完整的树。这样我们只需能够快速求出两棵树合并后得到新树的直径即可解决这个问题。

设合并的两棵树是 Ta 和 Tb,合并后形成的新树是 T。记 Ta 的直径的两端点为 ua 和va,Tb 的直径的两端点为 ub 和 vb,则 T 的直径的两端点一定 ∈ {ua, ub, va, vb}(由反证法不难证明)。这样我们只需维护每个块的直径及直径的两端点。在合并两个块时,我们只需暴力求出 4 个点对之间的路径长度,进行比较即可。

在这个过程中我们需要除以原来两块的直径。在模的意义下,除以一个数等价于乘以这个数的逆元。时间复杂度为O(n2),期望得分 60 − 80 分。

我们考虑改进上面的做法,虽然有加边、删边操作,但事实上我们要求的点对之间的路

径长度都是原树上的路径。故我们可以通过对原树进行倍增预处理,每次在 O(logn) 的时间内求得点对间的最近公共祖先(lca),从而得到点对间的路径长度。

时间复杂度为O(nlogn),期望得分 100 分。

代码

#include<cstdio>
#include<algorithm>
#include<vector>
#define ll long long
#define mo 1000000007
#define UP 20
#define N 100010
using namespace std; struct point{
long x,y;
void make(long x,long y)
{
this->x=x;
this->y=y;
}
}root[N],b[N]; long n; long fa[N][UP+1],dep[N],father[N],w[N],a[N],len[N],c[N],out[N];
void init()
{ long i,j;
for(i=1;i<=n;i++){
for(j=1;(1<<j)<=dep[i];j++)
fa[i][j]=fa[fa[i][j-1]][j-1];
father[i]=i;
root[i].make(i,i);
w[i]=a[i];
}
} long lca(long x,long y)
{ long up,xx=x,yy=y;
if(dep[x]>dep[y])
swap(x,y);
for(up=UP;up>=0;up--)
if(dep[y]-(1<<up)>=dep[x])
y=fa[y][up];
up=UP;
while(x!=y){
while(up>=0&&fa[x][up]==fa[y][up])
up--;
if(up<0)break;
x=fa[x][up];
y=fa[y][up];
up--;
}
if(x==y)
return len[xx]+len[yy]-2*len[x]+a[x];
else
return len[xx]+len[yy]-2*len[fa[x][0]]+a[fa[x][0]];
} vector<long>map[N];
bool ok[N];
void dfs(long now)
{ long i,to,next;
ok[now]=true;
for(i=0;i<map[now].size();i++){
to=map[now][i];
if(!ok[to]){
fa[to][0]=now;
dep[to]=dep[now]+1;
len[to]=a[to]+len[now];
dfs(to);
}
}
} long ksm(long a,long b)
{
if(b>1)
if(b&1)
return (ll)ksm((ll)a*a%mo,b>>1)*a%mo;
else
return ksm((ll)a*a%mo,b>>1);
else return a;
} long cha(long x)
{
return (father[x]==x)?x:father[x]=cha(father[x]);
}
void bin(long x,long y)
{
father[cha(x)]=cha(y);
} int main()
{ long i,xx,yy,r1,r2,r3,r4,w1,w2,w3,w4,maxx;
long long ans=1;
scanf("%ld",&n);
for(i=1;i<=n;i++){
scanf("%ld",&a[i]);
ans=ans*a[i]%mo;
}
out[n]=ans;
for(i=1;i<n;i++){
scanf("%ld%ld",&xx,&yy);
b[i].make(xx,yy);
map[xx].push_back(yy);
map[yy].push_back(xx);
}
dfs(1);
init();
for(i=1;i<n;i++)
scanf("%ld",&c[i]);
for(i=n-1;i>=1;i--){
xx=cha(b[c[i]].x);
yy=cha(b[c[i]].y);
r1=root[cha(xx)].x;
r2=root[cha(xx)].y;
r3=root[cha(yy)].x;
r4=root[cha(yy)].y;
w1=lca(r1,r3);
w2=lca(r1,r4);
w3=lca(r2,r3);
w4=lca(r2,r4);
maxx=max(w1,max(w2,max(w3,max(w4,max(w[xx],w[yy])))));
ans=ans*ksm(w[xx],mo-2)%mo*ksm(w[yy],mo-2)%mo*maxx%mo;
bin(xx,yy);
if(maxx==w1)
root[cha(xx)].make(r1,r3);
if(maxx==w2)
root[cha(xx)].make(r1,r4);
if(maxx==w3)
root[cha(xx)].make(r2,r3);
if(maxx==w4)
root[cha(xx)].make(r2,r4);
if(maxx==w[xx])
root[cha(xx)].make(r1,r2);
if(maxx==w[yy])
root[cha(xx)].make(r3,r4);
w[cha(xx)]=maxx;
out[i]=ans;
}
for(i=1;i<=n;i++)
printf("%ld\n",out[i]);
return 0;
}

JZOJ 5286. 【NOIP2017提高A组模拟8.16】花花的森林 (Standard IO)的更多相关文章

  1. JZOJ 【NOIP2017提高A组模拟9.14】捕老鼠

    JZOJ [NOIP2017提高A组模拟9.14]捕老鼠 题目 Description 为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里的仓库灭灭鼠.于是,猫被农夫约派去捕 ...

  2. [JZOJ 100026] [NOIP2017提高A组模拟7.7] 图 解题报告 (倍增)

    题目链接: http://172.16.0.132/senior/#main/show/100026 题目: 有一个$n$个点$n$条边的有向图,每条边为$<i,f(i),w(i)>$,意 ...

  3. 【NOIP2017提高A组模拟9.7】JZOJ 计数题

    [NOIP2017提高A组模拟9.7]JZOJ 计数题 题目 Description Input Output Sample Input 5 2 2 3 4 5 Sample Output 8 6 D ...

  4. JZOJ 100029. 【NOIP2017提高A组模拟7.8】陪审团

    100029. [NOIP2017提高A组模拟7.8]陪审团 Time Limits: 1000 ms  Memory Limits: 131072 KB  Detailed Limits   Got ...

  5. JZOJ 5328. 【NOIP2017提高A组模拟8.22】世界线

    5328. [NOIP2017提高A组模拟8.22]世界线 (File IO): input:worldline.in output:worldline.out Time Limits: 1500 m ...

  6. JZOJ 5329. 【NOIP2017提高A组模拟8.22】时间机器

    5329. [NOIP2017提高A组模拟8.22]时间机器 (File IO): input:machine.in output:machine.out Time Limits: 2000 ms M ...

  7. JZOJ 5307. 【NOIP2017提高A组模拟8.18】偷窃 (Standard IO)

    5307. [NOIP2017提高A组模拟8.18]偷窃 (Standard IO) Time Limits: 1000 ms Memory Limits: 262144 KB Description ...

  8. JZOJ 5305. 【NOIP2017提高A组模拟8.18】C (Standard IO)

    5305. [NOIP2017提高A组模拟8.18]C (Standard IO) Time Limits: 1000 ms Memory Limits: 131072 KB Description ...

  9. 【NOIP2017提高A组模拟9.17】信仰是为了虚无之人

    [NOIP2017提高A组模拟9.17]信仰是为了虚无之人 Description Input Output Sample Input 3 3 0 1 1 7 1 1 6 1 3 2 Sample O ...

随机推荐

  1. day35-子进程的开启

    #1.异步非阻塞: import os from multiprocessing import Process def func(): print('子进程:',os.getpid()) if __n ...

  2. 西甲官方APP承认监听球迷,或给国内应用带来新思路

    在此前,一般巨头或者官方推出的产品.应用等总是值得信赖的.出问题的话一般都是"不可抗拒的外力因素",比如被黑客攻破导致用户隐私被窃取等.但自从Facebook的用户隐私泄露丑闻被曝 ...

  3. Uber退出东南亚留下烂摊子,给“中国式并购”带来哪些启示

    当下,从全球范围内来看很多互联网企业都采用了"复制+粘贴"的疯狂推进模式.它们往往在某一个国家或地区取得领先优势后,就快速将相同模式在全球推进去占领当地市场.无论结果是一家独大占据 ...

  4. java中BigDecimal的四舍五入小记

    static class test{ public static void main(String[] args) { BigDecimal b=new BigDecimal(45); BigDeci ...

  5. Ribbon XML Editor 2019.01.23-Setup.zip(支持64位)

    RibbonXMLEditor是一款用于书写和测试customUI XML代码的国产工具,具有XML验证.Office文档压入.回调函数查询等多种功能. 可作为定制Office自定义界面有关程序开发的 ...

  6. Swiper中文网

    http://3.swiper.com.cn/api/Slides_grid/2014/1215/24.html slidesPerView :2,   即设置slider容器能够同时显示的slide ...

  7. 安装centos7后不能联网

    我们在安装centos的minimal版本后,在使用yum安装工具时会提示:cannot find a valid baseurl or repo:base/7/x86_64 这是因为不能联网导致的, ...

  8. js页面--年份自动增加

    ) { document.write("-" + new Date().getFullYear()); }</script> // 大于2017年自动加上 - 年份

  9. JavaScript replace() 方法+字符子集介绍(*)

    重点两部分知识点 1.javascript replace()函数用法 以下replace用法转载自w3cSchool:http://www.w3school.com.cn/jsref/jsref_r ...

  10. Java IO: FileOutputStream

    原文链接 作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) FileOutputStream可以往文件里写入字节流,它是OutputStream的子类, ...