题目链接:

小h的树上的朋友

时间限制:18000ms
单点时限:2000ms
内存限制:512MB

描述

小h拥有n位朋友。每位朋友拥有一个数值Vi代表他与小h的亲密度。亲密度有可能发生变化。

岁月流逝,小h的朋友们形成了一种稳定的树状关系。每位朋友恰好对应树上的一个节点。

每次小h想请两位朋友一起聚餐,他都必须把连接两位朋友的路径上的所有朋友都一起邀请上。并且聚餐的花费是这条路径上所有朋友的亲密度乘积。

小h很苦恼,他需要知道每一次聚餐的花销。小h问小y,小y当然会了,他想考考你。

输入

输入文件第一行是一个整数n,表示朋友的数目,从1开始编号。

输入文件第二行是n个正整数Vi,表示每位朋友的初始的亲密度。

接下来n-1行,每行两个整数u和v,表示u和v有一条边。

然后是一个整数m,代表操作的数目。每次操作为两者之一:

0 u v 询问邀请朋友u和v聚餐的花费

1 u v 改变朋友u的亲密度为v

1<=n,m<=5*105

Vi<=109

输出

对于每一次询问操作,你需要输出一个整数,表示聚餐所需的花费。你的答案应该模1,000,000,007输出。

样例输入
3
1 2 3
1 2
2 3
5
0 1 2
0 1 3
1 2 3
1 3 5
0 1 3
样例输出
2
6
15
题意:
中文的就不说了; 思路:
显然是一个线段树的题;
先dfs,把树映射到区间上同时求出每个点到根节点的花费,
0的时候询问:先找到lca;再dis[u]*dis[v]*w[lca]/(dis[lca]*dis[lca]);可以费马小定理快速幂求逆;
1的时候更新:dfs的时候找到了每个点的包含此点所以子节点的区间,把这个区间的dis都更新同时还要更新w[u]我就是这两个问题写漏了改了一夜晚; AC代码:
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
if(!p) { puts("0"); return; }
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9;
const int N=5e5+10;
const int maxn=1e3+10;
const double eps=1e-10; LL w[N],dis[N];
vector<int>ve[N]; int n,in[N],a[2*N],dep[N],cnt=0,out[N]; LL pow_mod(LL x,LL y)
{
LL s=1,base=x;
while(y)
{
if(y&1)s=s*base%mod;
base=base*base%mod;
y>>=1;
}
return s;
} void dfs(int x,int deep,int fa)
{
cnt++;
in[x]=cnt;
a[cnt]=x;
dep[x]=deep;
int len=ve[x].size();
For(i,0,len-1)
{
int y=ve[x][i];
if(y==fa)continue;
dis[y]=dis[x]*w[y]%mod;
dfs(y,deep+1,x);
cnt++;
a[cnt]=x;
}
out[x]=cnt;
}
struct Tree
{
int l,r,lca;
LL dis;
}tr[8*N];
void pushdown(int o)
{
tr[2*o].dis=tr[2*o].dis*tr[o].dis%mod;
tr[2*o+1].dis=tr[2*o+1].dis*tr[o].dis%mod;
tr[o].dis=1;
}
void build(int o,int L,int R)
{
tr[o].l=L;
tr[o].r=R;
tr[o].dis=1;
if(L==R)
{
tr[o].dis=dis[a[L]];
tr[o].lca=a[L];
return ;
}
int mid=(L+R)>>1;
build(2*o,L,mid);
build(2*o+1,mid+1,R);
if(dep[tr[2*o].lca]>=dep[tr[2*o+1].lca])tr[o].lca=tr[2*o+1].lca;
else tr[o].lca=tr[2*o].lca;
}
void update(int o,int L,int R,LL val)
{
if(tr[o].l>=L&&tr[o].r<=R)
{
tr[o].dis=tr[o].dis*val%mod;
return ;
}
int mid=(tr[o].l+tr[o].r)>>1; if(L>mid)update(2*o+1,L,R,val);
else if(R<=mid)update(2*o,L,R,val);
else {
update(2*o,L,mid,val);
update(2*o+1,mid+1,R,val);
}
}
int querylca(int o,int L,int R)
{ if(tr[o].l>=L&&tr[o].r<=R)return tr[o].lca;
int mid=(tr[o].l+tr[o].r)>>1;
if(R<=mid)return querylca(2*o,L,R);
else if(L>mid)return querylca(2*o+1,L,R);
else
{
int fl=querylca(2*o,L,mid),fr=querylca(2*o+1,mid+1,R);
if(dep[fl]<=dep[fr])return fl;
else return fr;
}
}
LL query(int o,int pos)
{
if(tr[o].l==tr[o].r&&tr[o].l==pos)return tr[o].dis;
int mid=(tr[o].l+tr[o].r)>>1;
pushdown(o);
if(pos>mid)return query(2*o+1,pos);
return query(2*o,pos);
}
int main()
{
read(n);
For(i,1,n)read(w[i]);
int u,v;
For(i,1,n-1)
{
read(u);read(v);
ve[u].push_back(v);
ve[v].push_back(u);
}
dis[1]=w[1];
dfs(1,0,0);
build(1,1,cnt);
int q,f;
read(q);
while(q--)
{
read(f);read(u);read(v);
if(f)
{
LL temp=w[u];
w[u]=(LL)v;
update(1,in[u],out[u],w[u]*pow_mod(temp,mod-2)%mod);
}
else
{
if(in[u]>in[v])swap(u,v);
int lca=querylca(1,in[u],in[v]);
LL temp=query(1,in[lca]);
temp=pow_mod(temp,mod-2);
temp=temp*temp%mod;
LL ans=query(1,in[u])*query(1,in[v])%mod*temp%mod*w[lca]%mod;
cout<<ans<<"\n";
}
}
return 0;
}

  

hihocoder-1347 小h的树上的朋友(lca+线段树)的更多相关文章

  1. hihocoder 1347 小h的树上的朋友

    传送门 时间限制:18000ms单点时限:2000ms内存限制:512MB 描述 小h拥有$n$位朋友.每位朋友拥有一个数值$V_i$代表他与小h的亲密度.亲密度有可能发生变化.岁月流逝,小h的朋友们 ...

  2. 2018 ACMICPC上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节)

    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节) 链接:https://ac.nowcoder.co ...

  3. [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)

    [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...

  4. BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )

    树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...

  5. [BZOJ3307]:雨天的尾巴(LCA+树上差分+权值线段树)

    题目传送门 题目描述: N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式: 第一 ...

  6. 51nod 1463 找朋友 (扫描线+线段树)

    1463 找朋友  基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80 难度:5级算法题  收藏  关注 给定: 两个长度为n的数列A .B 一个有m个元素的集合K 询问Q次 每次询 ...

  7. 51Nod1766 树上的最远点对 ST表 LCA 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1766.html 题目传送门 - 51Nod1766 题意 n个点被n-1条边连接成了一颗树,给出a~ ...

  8. 51nod 1463 找朋友(线段树+离线处理)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序, ...

  9. [bzoj3306]树——树上倍增+dfs序+线段树

    Brief Description 您需要写一种数据结构,支持: 更改一个点的点权 求一个子树的最小点权 换根 Algorithm Design 我们先忽略第三个要求. 看到要求子树的最小点权,我们想 ...

随机推荐

  1. Maven单元测试

    // SKU码:系列前3位+6位年月日+3位序号(自动生产,取数据库中当天最大的,没有就赋值位001) // 订单编号:BRD+6位年月日+5位序号 // // 退单号:BRT+6位年月日+3位序号 ...

  2. 关于错误Access Violation和too many consecutive exceptions 解决方法

    关于错误Access Violation和too many consecutive exceptions 解决方法 “如果DLL中用到了DELPHI的string类型,则DLL和主程序中都需要加上Sh ...

  3. Python练习题–持续更新

    1.你是一个高级测试工程师,现在要做性能测试,需要你写一个函数,批量生成一些注册使用的账号. 产生的账号是以@163.com结尾,长度由用户输入,产生多少条也由用户输入,用户名不能重复,用户名必须由大 ...

  4. 洛谷 P1503鬼子进村

    题目背景 小卡正在新家的客厅中看电视.电视里正在播放放了千八百次依旧重播的<亮剑>,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战. 题目描述 描述 县城里 ...

  5. 航空售票系统设计分析(Markdownpad2图片服务器上传无法显示)

    一.体系结构设计 1.系统原型图 2.体系结构环境图 3.构建结构图 二.人机交互界面设计 1.用户分析结果及建议 本次分析的主要目标关注用户评论反馈,对反馈进行归纳,设计出用户喜欢的界面样式.用户的 ...

  6. How do I get an image from an UIButton? 如何获取uibutton设置的uiimage

    UIImage*img =[button imageForState:UIControlStateNormal];

  7. How to fill the background with image in landscape in IOS? 如何使image水平铺满屏幕

    UIImageView *backgroundImage = [[UIImageView alloc] initWithFrame:self.view.frame];    [backgroundIm ...

  8. 【sourcetree】sourcetree连接远程仓库需要登陆但是一直登陆不上的问题 解决方法

    授权类型选用 基础 .只需要登陆你在bitbucket的用户名和密码 如下 .即可成功连接远程仓库

  9. openERP邮件(发信、收信)

    openERP里的邮件处理主要有个2个模块处理 mail -核心 fetchmail -接收邮件     Alias domain和alias name     配置domain alias. Set ...

  10. Java学习之String StringBuffer StringBuilder区别

    1.String:对象长度是不可变的,是线程安全. 2.StringBuffer:对象长度是可变的,是线程安全. 3.StringBuilder:对象长度是可变,不是线程安全.