题目

动态修改边权,强制在线询问树的直径。


分析

设 \(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的更多相关文章

  1. BZOJ 4034 [HAOI2015]树上操作(欧拉序+线段树)

    题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增 ...

  2. LightOJ 1370 Bi-shoe and Phi-shoe 欧拉函数+线段树

    分析:对于每个数,找到欧拉函数值大于它的,且标号最小的,预处理欧拉函数,然后按值建线段树就可以了 #include <iostream> #include <stdio.h> ...

  3. loj1370(欧拉函数+线段树)

    传送门:Bi-shoe and Phi-shoe 题意:给出多个n(1<=n<=1e6),求满足phi(x)>=n的最小的x之和. 分析:先预处理出1~1e6的欧拉函数,然后建立一颗 ...

  4. LOJ #2142. 「SHOI2017」相逢是问候(欧拉函数 + 线段树)

    题意 给出一个长度为 \(n\) 的序列 \(\{a_i\}\) 以及一个数 \(p\) ,现在有 \(m\) 次操作,每次操作将 \([l, r]\) 区间内的 \(a_i\) 变成 \(c^{a_ ...

  5. BZOJ 4034 树上操作(树的欧拉序列+线段树)

    刷个清新的数据结构题爽一爽? 题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x ...

  6. [LNOI] 相逢是问候 || 扩展欧拉函数+线段树

    原题为2017六省联考的D1T3 给出一个序列,m次操作,模数p和参数c 操作分为两种: 1.将[l,r]区间内的每个数x变为\(c^x\) 2.求[l,r]区间内数的和%p 首先,我们要了解一些数论 ...

  7. [BZOJ4026]dC Loves Number Theory 欧拉函数+线段树

    链接 题意:给定长度为 \(n\) 的序列 A,每次求区间 \([l,r]\) 的乘积的欧拉函数 题解 考虑离线怎么搞,将询问按右端点排序,然后按顺序扫这个序列 对于每个 \(A_i\) ,枚举它的质 ...

  8. BZOJ 4034: [HAOI2015]树上操作 [欧拉序列 线段树]

    题意: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a . 操作 3 :询问某个节点 x 到根的路径中所有点的点权和. 显然树链剖分可做 ...

  9. 欧拉筛法模板and 洛谷 P3383 【模板】线性筛素数(包括清北的一些方法)

    题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入格式 第一行包含两个正整数N.M,分别表示查询的范围和查询的个数. 接下来M行每行包含一个不小于1 ...

  10. bzoj4869: [Shoi2017]相逢是问候(欧拉函数+线段树)

    这题是六省联考的...据说数据还出了点锅,心疼六省选手QAQ 首先要知道扩展欧拉定理... 可以发现每次区间操作都会使模数进行一次phi操作,而一个数最多取logp次phi就会变成1,这时后面的指数就 ...

随机推荐

  1. 使用GDI时如何确定是否有内存泄漏

    在创建GDI对象时,比如创建笔,画刷等对象时,在调用完之后忘记删除对象了,会造成内存泄漏 我们可以通过任务管理器来快速的查看 启动任务管理器(右键单击Windows任务栏以选择任务管理器) 在Wind ...

  2. git回退至指定版本,并更新远程仓库

    1. git log   查到commit记录 2.复制 commit 后面的id 3. git reset --hard  commit 后面的id   // 回退 4. 强制更新远程仓库  git ...

  3. 【LeetCode栈与队列#04】逆波兰表达式求值(仍然是经典的栈操作)

    逆波兰表达式求值 力扣题目链接(opens new window) 根据 逆波兰表示法,求表达式的值. 有效的运算符包括 + , - , * , / .每个运算对象可以是整数,也可以是另一个逆波兰表达 ...

  4. 【Azure 应用服务】调用Azure REST API来获取 App Service的访问限制信息(Access Restrictions)以及修改

    问题描述 昨天的博文中(https://www.cnblogs.com/lulight/p/17099179.html)介绍了使用Python SDK 来获取App Service的访问限制信息,那么 ...

  5. 【Azure 云服务】指标哪去了?在执行 Swap (交换生产部署和Staging部署) 操作后看不见云服务的旧指标

    问题描述 打开云服务(Cloud Service)的Metrics页面,发现过去了指标不见了? 以虚点构成无数据的图表. 问题解答 查看云服务的活动日志(Activity Logs),发现最近执行的操 ...

  6. spark读取和处理zip、gzip、excel、等各种文件最全的技巧总结

    一.当后缀名为zip.gzip,spark可以自动处理和读取 1.spark非常智能,如果一批压缩的zip和gzip文件,并且里面为一堆text文件时,可以用如下方式读取或者获取读取后的schema ...

  7. Mysql常用存储引擎以及区别?

    InnoDB:是Mysql的默认存储引擎,支持事务.外键.如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新.删除操作,那么InnoDB存 ...

  8. Thinkphp6 自定义命令创建类文件

    以创建控制器为例 1.先通过 think 命令创建一个make文件,效果如下图: php think make:command make/MyController 2.修改上面创建的文件[MyCont ...

  9. [MAUI 项目实战] 音乐播放器(二):播放内核

    播放控制服务 IMusicControlService: 播放控制类,用于当前平台播放器对象的操作,对当前所播放曲目的暂停/播放,下一首/上一首,快进快退(寻迹),随机.单曲模式等功能的控制. 播放控 ...

  10. Python Numpy 中的打印设置函数set_printoptions

    一 概述 np.set_printoptions()用于控制Python中小数的显示精度. 二 解析 np.set_printoptions(precision=None, threshold=Non ...