hihocoder-1347 小h的树上的朋友(lca+线段树)
题目链接:
小h的树上的朋友
描述
小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+线段树)的更多相关文章
- hihocoder 1347 小h的树上的朋友
传送门 时间限制:18000ms单点时限:2000ms内存限制:512MB 描述 小h拥有$n$位朋友.每位朋友拥有一个数值$V_i$代表他与小h的亲密度.亲密度有可能发生变化.岁月流逝,小h的朋友们 ...
- 2018 ACMICPC上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节)
2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节) 链接:https://ac.nowcoder.co ...
- [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)
[51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...
- BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )
树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...
- [BZOJ3307]:雨天的尾巴(LCA+树上差分+权值线段树)
题目传送门 题目描述: N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式: 第一 ...
- 51nod 1463 找朋友 (扫描线+线段树)
1463 找朋友 基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80 难度:5级算法题 收藏 关注 给定: 两个长度为n的数列A .B 一个有m个元素的集合K 询问Q次 每次询 ...
- 51Nod1766 树上的最远点对 ST表 LCA 线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1766.html 题目传送门 - 51Nod1766 题意 n个点被n-1条边连接成了一颗树,给出a~ ...
- 51nod 1463 找朋友(线段树+离线处理)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序, ...
- [bzoj3306]树——树上倍增+dfs序+线段树
Brief Description 您需要写一种数据结构,支持: 更改一个点的点权 求一个子树的最小点权 换根 Algorithm Design 我们先忽略第三个要求. 看到要求子树的最小点权,我们想 ...
随机推荐
- HDU 1242 dFS 找目标最短路
//多个起点,要最短得目标,不妨倒过来从目标出发,去找最近的点更新!!!!!!递归时思路要清楚 #include<iostream> #include<cstring> usi ...
- Hive入门及常用指令
基础命令show databases; # 查看某个数据库use 数据库; # 进入某个数据库show tables; # 展示所有表desc 表名; # 显示表结构show partitions 表 ...
- Linux下使用vi新建文件保存文件时遇到错误:E212: Can't open file for writing
出现E212: Can't open file for writing的问题是由于权限问题导致的,解决方法有以下思路: 1.使用root进行登录,然后再操作. 2.在使用命令时,前面加sudo. 3. ...
- jquery+css实现邮箱自动补全
今天在公司做一个电子商务网站的注册会员时,要求用户在电子邮箱文本框中输入时,给与热点提示常用的电子邮箱,帮助用户选择,提高体验效果.下面是用Jquery+css实现的邮箱自动补全,供大家参考和学习. ...
- android Activity生命周期的例子
package com.example.yanlei.yl2; import android.app.AlertDialog; import android.content.DialogInterfa ...
- jQuery.ajax()方法中參数具体解析
前言 在项目开发中,为了实现异步向服务端发起请求,最常常使用的就是jQuery.ajax方法了.刚開始需求比較简单,调用jQuery.ajax方法时要传的參数也就那几个常见的參数:url/data/d ...
- 【深度探索c++对象模型】关于对象
Linux进程的五个段 BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属 ...
- SolidEdge 工程图中如何显示彩色工程图
点击这个按钮,然后更新视图 效果如下图所示,注意如果你的装配图(.dft文件)是单独拷贝出来的,装配图所引用的零件无法追溯到,则无法渲染这些零件,因此无法制作彩色工程图.
- SolidEdge 如何由装配图快速进行标注和零件序号编写 制作BOM表
点击"零件明细表",然后点击要生成序号的视图,然后点击前面两项(自动标号和放置清单),点击完成后效果如下图所示. 在点击完成之前,先点击他前面的一个按钮,取消勾选"项 ...
- LOCAL_CFLAGS参数说明
1.-Wall 是打开警告开关 2.-O 代表默认优化,可选:-O0不优化,-O1低级优化,-O2中级优化,-O3高级优化,-Os代码空间优化 3.-g 是生成调试信息,生成的可执行文件具有和源代码关 ...