P4315 月下“毛景树”

题目描述

毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园。 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里。

爬啊爬爬啊爬毛毛虫爬到了一颗小小的“毛景树”下面,发现树上长着他最爱吃的毛毛果 “毛景树”上有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的。但是这棵“毛景树”有着神奇的魔力,他能改变树枝上毛毛果的个数:

Change k w:将第k条树枝上毛毛果的个数改变为w个。

Cover u v w:将节点u与节点v之间的树枝上毛毛果的个数都改变为w个。

Add u v w:将节点u与节点v之间的树枝上毛毛果的个数都增加w个。 由于毛毛虫很贪,于是他会有如下询问:

Max u v:询问节点u与节点v之间树枝上毛毛果个数最多有多少个。

Solution

树剖

注意线段树下推标记时分清楚对子节点标记的影响

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define LL long long
#define REP(i, x, y) for(int i = (x);i <= (y);i++)
using namespace std;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 100019,INF = 1e9 + 19;
int head[maxn],nume = 1;
struct Node{
int v,dis,nxt;
}E[maxn << 3];
void add(int u,int v,int dis){
E[++nume].nxt = head[u];
E[nume].v = v;
E[nume].dis = dis;
head[u] = nume;
}
int num;
int size[maxn], wson[maxn], dep[maxn], fa[maxn], val[maxn];
int top[maxn], pos[maxn], ori[maxn], tot;
void dfs1(int u, int F){
size[u] = 1;
for(int i = head[u];i;i = E[i].nxt){
int v = E[i].v;
if(v == F)continue;
val[v] = E[i].dis;
dep[v] = dep[u] + 1;
fa[v] = u;
dfs1(v, u);
size[u] += size[v];
if(size[v] > size[wson[u]])wson[u] = v;
}
}
void dfs2(int u, int TP){
top[u] = TP;
pos[u] = ++tot;
ori[tot] = u;
if(!wson[u])return ;
dfs2(wson[u], TP);
for(int i = head[u];i;i = E[i].nxt){
int v = E[i].v;
if(v == fa[u] || v == wson[u])continue;
dfs2(v, v);
}
}
#define lid (id << 1)
#define rid (id << 1) | 1
struct seg_tree{
int l, r;
int max;
int add, set;
}tree[maxn << 2];
void pushup(int id){tree[id].max = max(tree[lid].max, tree[rid].max);}
void build(int id, int l, int r){
tree[id].l = l, tree[id].r = r, tree[id].set = -1;
if(l == r){
tree[id].max = val[ori[l]];
return ;
}
int mid = (l + r) >> 1;
build(lid, l, mid), build(rid, mid + 1, r);
pushup(id);
}
void pushdown(int id){
if(tree[id].set != -1){
int v = tree[id].set;
tree[lid].max = tree[rid].max = v;
tree[lid].set = tree[rid].set = v;
tree[lid].add = tree[rid].add = 0;
tree[id].add = 0;
tree[id].set = -1;
}
if(tree[id].add != 0){
int v = tree[id].add;
tree[lid].max += v;
tree[rid].max += v;
if(tree[lid].set != -1)tree[lid].set += v;
if(tree[rid].set != -1)tree[rid].set += v;
tree[lid].add += v;
tree[rid].add += v;
tree[id].add = 0;
}
}
void update(int id, int v, int l, int r, int o){
pushdown(id);
if(tree[id].l == l && tree[id].r == r){
if(o == 1){//1为全改变
tree[id].max = v;
tree[id].set = v;
}
else{//0为区间加
tree[id].max += v;
tree[id].add += v;
}
return ;
}
int mid = (tree[id].l + tree[id].r) >> 1;
if(mid < l)update(rid, v, l, r, o);
else if(mid >= r)update(lid, v, l, r, o);
else update(lid, v, l, mid, o), update(rid, v, mid + 1, r, o);
pushup(id);
}
int query(int id, int l, int r){
pushdown(id);
if(tree[id].l == l && tree[id].r == r)return tree[id].max;
int mid = (tree[id].l + tree[id].r) >> 1;
if(mid < l)return query(rid, l, r);
else if(mid >= r)return query(lid, l, r);
else return max(query(lid, l, mid), query(rid, mid + 1, r));
}
void uprange(int x, int y, int v, int o){
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]])swap(x, y);
update(1, v, pos[top[x]], pos[x], o);
x = fa[top[x]];
}
if(x == y)return ;
if(dep[x] > dep[y])swap(x, y);
update(1, v, pos[x] + 1, pos[y], o);
}
int Q_max(int x, int y){
int ret = 0;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]])swap(x, y);
ret = max(ret, query(1, pos[top[x]], pos[x]));
x = fa[top[x]];
}
if(x == y)return ret;
if(dep[x] > dep[y])swap(x, y);
ret = max(ret, query(1, pos[x] + 1, pos[y]));
return ret;
}
struct EDG{int x, y;}I[maxn];
void init(){
num = RD();
REP(i, 1, num - 1){
int u = RD(), v = RD(), dis = RD();
I[i] = (EDG){u, v};
add(u, v, dis), add(v, u, dis);
}
dep[1] = 1;
dfs1(1, -1);
dfs2(1, 1);
build(1, 1, num);
}
void solve(){
char cmd[19];
while(1){
scanf("%s", cmd);
if(cmd[0] == 'S')return ;
else if(cmd[0] == 'C' && cmd[1] == 'h'){
int k = RD(), w = RD();
uprange(I[k].x, I[k].y, w, 1);
}
else if(cmd[0] == 'C' && cmd[1] == 'o'){
int x = RD(), y = RD(), w = RD();
uprange(x, y, w, 1);
}
else if(cmd[0] == 'A'){
int x = RD(), y = RD(), w = RD();
uprange(x, y, w, 0);
}
else{
int x = RD(), y = RD();
printf("%d\n", Q_max(x, y));
}
}
}
int main(){
init();
solve();
return 0;
}

P4315 月下“毛景树”的更多相关文章

  1. P4315 月下“毛景树”(树链剖分)

    P4315 月下"毛景树"(树链剖分) 题面 简述: 边权转点权(在dfs1处转换) 把一条边权赋值在深度更深的上 需要实现对单边权的染色 , 路径边权的染色 , 路径边权的增加 ...

  2. P4315 月下“毛景树” (树链剖分+边剖分+区间覆盖+区间加+区间最大值)

    题目链接:https://www.luogu.org/problem/P4315 题目大意: 有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的.但是这棵“毛景树”有着神奇的魔力 ...

  3. 洛谷P4315 月下“毛景树”

    题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...

  4. P4315 月下“毛景树”[树剖]

    题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...

  5. [洛谷P4315] 月下”毛景“树

    题目链接: 点我 题目分析: 树剖.将边权下放到下方点上(为什么要选深度更深的点?一个父亲可能对应多个儿子,但一个儿子只有一个父亲,即可以保证每个点只保存一条边权)成为经典点权+树剖裸题 注意链计算时 ...

  6. 洛谷P4315 月下“毛景树”(树剖+线段树)

    传送门 woc这该死的码农题…… 把每一条边转化为它连接的两点中深度较深的那一个,然后就可以用树剖+线段树对路径进行修改了 然后顺便注意在上面这种转化之后,树剖的时候不能搞$LCA$ 然后是几个注意点 ...

  7. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  8. 【BZOJ1984】月下“毛景树” 树链剖分+线段树

    [BZOJ1984]月下"毛景树" Description 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校 ...

  9. 【BZOJ-1984】月下“毛景树” 树链剖分

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1314  Solved: 416[Submit][Status][Discu ...

随机推荐

  1. Linux期中总结

    在MOOC八周内容高度概括总结如下 (一)计算机是如何工作的 冯诺依曼体系结构——核心:存储程序计算机; X86汇编基础 (二)操作系统是如何工作的 三个法宝——存储程序计算机.函数调用堆栈.中断机制 ...

  2. Linux内核第六节 20135332武西垚

    如何描述一个进程:进程描述符的数据结构: 如何创建一个进程:内核是如何执行的,以及新创建的进程从哪里开始执行: 使用gdb跟踪新进程的创建过程. 进程的描述 操作系统三大功能: 进程管理(最核心最基础 ...

  3. JsTree使用一例

    SearchDesignPatent.treeContainer().jstree({ 'core' : { 'data' : json.data }, }).bind('click.jstree', ...

  4. Appium学习笔记4_元素定位方法

    Appium之元素定位,如果对Android上如何使用工具获取页面元素有问题的,请转战到这:http://www.cnblogs.com/taoSir/p/4816382.html. 下面主要是针对自 ...

  5. [CB]2018年中国智能手机市场出货量

    Canalys:2018年中国智能手机市场出货量同比跌逾14% https://www.cnbeta.com/articles/tech/813267.htm 市场调研机构Canalys今日公布中国智 ...

  6. js函數

    函數是什麼?函數就是被事件驅動或者調用執行的可重複的代碼塊. 函數聲明: 使用關鍵詞function,關鍵詞function大小敏感. function a{代碼塊} 局部變量: 在函數內部聲明的變量 ...

  7. Struts2 Intercepter 笔记

    以前一直对Struts2的自定义拦截器(intercepter)不是很清楚,今天仔细研究了下,终于搞懂了,现在记录对拦截器的总结如下: 1:自定义拦截器的作用一般就是用来实现系统权限控制比较多: 2: ...

  8. pgm15

    这部分我们讨论结构学习,也就是 graph 的边我们并不清楚.很自然我们可以用 fully observed 数据来做,但是也可能碰到有 missing data 的情况.一般来说前者是比较常见的.就 ...

  9. BZOJ3881[Coci2015]Divljak——AC自动机+树状数组+LCA+dfs序+树链的并

    题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  10. LightOJ 1030 【概率DP求期望】

    借鉴自:https://www.cnblogs.com/keyboarder-zsq/p/6216762.html 题意:n个格子,每个格子有一个值.从1开始,每次扔6个面的骰子,扔出几点就往前几步, ...