#欧拉序,线段树#洛谷 6845 [CEOI2019] Dynamic Diameter
题目
动态修改边权,强制在线询问树的直径。
分析
设 \(dis[x]\) 表示 \(x\) 到1号点的距离。
那么树的直径就可以表示成 \(dis[x]+dis[y]-2*dis[lca]\)
只需要保证 \(lca\) 被夹在 \(x,y\) 之间,欧拉序可以满足这样的条件。
用欧拉序将树拍成一个序列,也就是要询问 \(\max_{i\leq j\leq k}\{dis[i]+dis[k]-2*dis[j]\}\)
维护区间最大值,区间最小值,\(dis[i]-2*dis[j]\) 的最大值,\(dis[k]-2*dis[j]\) 的最大值,以及区间的答案。
修改边权相当于在子树区间加,直接用线段树维护就可以了。
代码
#include <cstdio>
#include <cctype>
using namespace std;
const int N=200011; typedef long long lll;
struct node{int y; lll w; int next;}e[N];
int dfn[N],nfd[N],as[N],n,et=1,m,tot,rfn[N];
lll lim,lans,dis[N],w[N<<2],lazy[N<<2],lmx[N<<2],rmx[N<<2],mx[N<<2],mn[N<<2];
lll iut(){
lll ans=0,f=1; char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void print(lll ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
lll min(lll a,lll b){return a<b?a:b;}
lll max(lll a,lll b){return a>b?a:b;}
void dfs(int x,int fa){
nfd[dfn[x]=++tot]=x;
for (int i=as[x];i;i=e[i].next)
if (e[i].y!=fa){
dis[e[i].y]=dis[x]+e[i].w,
dfs(e[i].y,x),nfd[++tot]=x;
}
rfn[x]=tot;
}
void pup(int k){
mn[k]=min(mn[k<<1],mn[k<<1|1]),mx[k]=max(mx[k<<1],mx[k<<1|1]);
lmx[k]=max(max(lmx[k<<1],lmx[k<<1|1]),mx[k<<1]-2*mn[k<<1|1]);
rmx[k]=max(max(rmx[k<<1],rmx[k<<1|1]),mx[k<<1|1]-2*mn[k<<1]);
w[k]=max(max(w[k<<1],w[k<<1|1]),max(lmx[k<<1]+mx[k<<1|1],mx[k<<1]+rmx[k<<1|1]));
}
void build(int k,int l,int r){
if (l==r){
mn[k]=mx[k]=dis[nfd[l]],
lmx[k]=rmx[k]=-dis[nfd[l]];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pup(k);
}
void ptag(int k,lll z){mn[k]+=z,mx[k]+=z,lmx[k]-=z,rmx[k]-=z,lazy[k]+=z;}
void update(int k,int l,int r,int x,int y,lll z){
if (l==x&&r==y){
ptag(k,z);
return;
}
int mid=(l+r)>>1;
if (lazy[k]){
ptag(k<<1,lazy[k]);
ptag(k<<1|1,lazy[k]);
lazy[k]=0;
}
if (y<=mid) update(k<<1,l,mid,x,y,z);
else if (x>mid) update(k<<1|1,mid+1,r,x,y,z);
else update(k<<1,l,mid,x,mid,z),update(k<<1|1,mid+1,r,mid+1,y,z);
pup(k);
}
int main(){
n=iut(),m=iut(),lim=iut();
for (int i=1;i<n;++i){
int x=iut(),y=iut(); lll w=iut();
e[++et]=(node){y,w,as[x]},as[x]=et;
e[++et]=(node){x,w,as[y]},as[y]=et;
}
dfs(1,0),build(1,1,tot);
for (int i=1;i<=m;++i){
int o=(iut()+lans)%(n-1)+1; lll W=(iut()+lans)%lim;
int x=e[o<<1].y,y=e[o<<1|1].y;
if (dis[x]<dis[y]) x^=y,y^=x,x^=y;
update(1,1,tot,dfn[x],rfn[x],W-e[o<<1].w);
e[o<<1].w=e[o<<1|1].w=W,print(lans=w[1]),putchar(10);
}
return 0;
}
#欧拉序,线段树#洛谷 6845 [CEOI2019] Dynamic Diameter的更多相关文章
- BZOJ 4034 [HAOI2015]树上操作(欧拉序+线段树)
题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增 ...
- LightOJ 1370 Bi-shoe and Phi-shoe 欧拉函数+线段树
分析:对于每个数,找到欧拉函数值大于它的,且标号最小的,预处理欧拉函数,然后按值建线段树就可以了 #include <iostream> #include <stdio.h> ...
- loj1370(欧拉函数+线段树)
传送门:Bi-shoe and Phi-shoe 题意:给出多个n(1<=n<=1e6),求满足phi(x)>=n的最小的x之和. 分析:先预处理出1~1e6的欧拉函数,然后建立一颗 ...
- LOJ #2142. 「SHOI2017」相逢是问候(欧拉函数 + 线段树)
题意 给出一个长度为 \(n\) 的序列 \(\{a_i\}\) 以及一个数 \(p\) ,现在有 \(m\) 次操作,每次操作将 \([l, r]\) 区间内的 \(a_i\) 变成 \(c^{a_ ...
- BZOJ 4034 树上操作(树的欧拉序列+线段树)
刷个清新的数据结构题爽一爽? 题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x ...
- [LNOI] 相逢是问候 || 扩展欧拉函数+线段树
原题为2017六省联考的D1T3 给出一个序列,m次操作,模数p和参数c 操作分为两种: 1.将[l,r]区间内的每个数x变为\(c^x\) 2.求[l,r]区间内数的和%p 首先,我们要了解一些数论 ...
- [BZOJ4026]dC Loves Number Theory 欧拉函数+线段树
链接 题意:给定长度为 \(n\) 的序列 A,每次求区间 \([l,r]\) 的乘积的欧拉函数 题解 考虑离线怎么搞,将询问按右端点排序,然后按顺序扫这个序列 对于每个 \(A_i\) ,枚举它的质 ...
- BZOJ 4034: [HAOI2015]树上操作 [欧拉序列 线段树]
题意: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a . 操作 3 :询问某个节点 x 到根的路径中所有点的点权和. 显然树链剖分可做 ...
- 欧拉筛法模板and 洛谷 P3383 【模板】线性筛素数(包括清北的一些方法)
题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入格式 第一行包含两个正整数N.M,分别表示查询的范围和查询的个数. 接下来M行每行包含一个不小于1 ...
- bzoj4869: [Shoi2017]相逢是问候(欧拉函数+线段树)
这题是六省联考的...据说数据还出了点锅,心疼六省选手QAQ 首先要知道扩展欧拉定理... 可以发现每次区间操作都会使模数进行一次phi操作,而一个数最多取logp次phi就会变成1,这时后面的指数就 ...
随机推荐
- 小程序中用css修改svg的颜色
记一下(#^.^#) <div class="svg"> <img src="./firefox-logo.svg" class=" ...
- 利用wiile双层循环打印各种星星---day06
# 十行十列小星星 j = 0 #定义行数 while j<10: #当行数小于10的时候 i=0 #定义列 while i <10: #当列小于10的时候 print('*',end=' ...
- TensorFlow 回归模型
TensorFlow 回归模型 首先,导入所需的库和模块.代码中使用了numpy进行数值计算,matplotlib进行数据可视化,tensorflow进行机器学习模型的构建和训练,sklearn进行多 ...
- 微信小程序测试点,9大方面全方位总结
微信小程序无需下载安装,用户在微信扫一扫或搜索即可使用,小程序版本类型可分为:开发版.体验版.正式版. 开发版.体验版无需审核,只需要给微信号权限,经过扫小程序的二维码就能访问,正式版本需要经过微信审 ...
- dos-基础用法
DOS(磁盘操作系统)是一个早期的基于命令行的操作系统,尽管现代操作系统已经发展为图形用户界面(GUI),但是了解和掌握一些基本的DOS命令仍然非常有用,尤其是在处理批处理脚本.网络管理或者在没有图形 ...
- 【技术积累】MySQL优化及进阶
MySql优化及进阶 一.MySQL体系结构 连接层:是一些客户端和链接服务,包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于 TCP/IP的通信 服务层:大多数的核心服务功能,如SQ ...
- 有了net/http, 为什么还要有gin
1. 简介 在Go语言中,net/http 包提供了一个强大且灵活的标准HTTP库,可以用来构建Web应用程序和处理HTTP请求.这个包是Go语言标准库的一部分,因此所有的Go程序都可以直接使用它.既 ...
- Ansible 基础入门
2)Ansible 介绍 Ansible 基本概念 Ansible 是一种自动化运维工具,基于 Paramiko 开发的,并且基于模块化工作,Ansible 是一种集成 IT 系统的配置管理.应用部署 ...
- Spring事务(一)-事务配置
事务是数据库操作最基本的单元,是逻辑上的一组操作,这一组操作在同一个会话中要么都执行成功,要么都失败,这也是事务的最基本特性--原子性.事务的作用是为了保证系统数据的正确性,因此,数据库应用程序中是会 ...
- Alt+Space 快速打开切换程序 - Everything - AutoHotKey
Alt+Space 快速打开切换程序 - Everything - AutoHotKey 需求 电脑切换任务 需要用鼠标找,效率比较低,用快捷键Alt+Space 打开列表,输入指定关键字回车,切换或 ...