1984: 月下“毛景树”

Time Limit: 20 Sec  Memory Limit: 64 MB
[Submit][Status][Discuss]

Description

毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园。 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里。爬啊爬~爬啊爬~~毛毛虫爬到了一颗小小的“毛景树”下面,发现树上长着他最爱吃的毛毛果~~~ “毛景树”上有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之间树枝上毛毛果个数最多有多少个。

Input

第一行一个正整数N。 接下来N-1行,每行三个正整数Ui,Vi和Wi,第i+1行描述第i条树枝。表示第i条树枝连接节点Ui和节点Vi,树枝上有Wi个毛毛果。 接下来是操作和询问,以“Stop”结束。

Output

对于毛毛虫的每个询问操作,输出一个答案。

Sample Input

4
1 2 8
1 3 7
3 4 9
Max 2 4
Cover 2 4 5
Add 1 4 10
Change 1 16
Max 2 4
Stop

Sample Output

9
16

【Data Range】
1<=N<=100,000,操作+询问数目不超过100,000。
保证在任意时刻,所有树枝上毛毛果的个数都不会超过10^9个。

HINT

Source

change应该比modify优先级高
这道题我没有压到100行以内
#include<iostream>
#include<cstring>
#include<cstdio>
#define inf 0x7fffffff
const int N = 100000 + 5;
using namespace std;
int cnt=1,n,sz; char ch[10];
int pos[N],bel[N],last[N],dep[N],siz[N],anc[N][20],id[N];
int ls[N<<2],rs[N<<2],mx[N<<2],l[N<<2],r[N<<2],mf[N<<2],af[N<<2],root,idd;
struct Edge{int to,next,v;}e[N<<1];
void insert(int u,int v,int w){e[++cnt].to = v; e[cnt].next = last[u]; e[cnt].v = w; last[u] = cnt;e[++cnt].to = u; e[cnt].next = last[v]; e[cnt].v = w; last[v] = cnt;
}
void build( int &k, int L, int R ){k = ++idd; l[idd] = L; r[idd] = R; mf[k] = -1;if( L == R ) return; int mid = (L+R)>>1;build( ls[k], L, mid ); build( rs[k], mid+1, R );
}
void update( int k ){mx[k] = max(mx[ls[k]],mx[rs[k]]);
}
void pushdown( int k ){if( l[k] == r[k] ) return;if( mf[k] != -1 ){af[ls[k]] = af[rs[k]] = 0;mx[ls[k]] = mx[rs[k]] = mf[ls[k]] = mf[rs[k]] = mf[k];mf[k] = -1;} if( af[k] ){mx[ls[k]] += af[k]; mx[rs[k]] += af[k];if( mf[ls[k]] != -1 ) mf[ls[k]] += af[k]; else af[ls[k]] += af[k];if( mf[rs[k]] != -1 ) mf[rs[k]] += af[k]; else af[rs[k]] += af[k];af[k] = 0;}
}
void change( int k, int x, int y, int v ){pushdown(k);if( x == l[k] && y == r[k] ){ mx[k] = mf[k] = v; return;}int mid = (l[k]+r[k])>>1;if( mid >= y ) change(ls[k],x,y,v);else if( mid < x ) change(rs[k],x,y,v);else {change(ls[k],x,mid,v);change(rs[k],mid+1,y,v);}update(k);
}
void modify( int k, int x, int y, int v ){pushdown(k);if( x == l[k] && y == r[k] ){ mx[k] += v; af[k] = v; return;}int mid = (l[k]+r[k])>>1;if( mid >= y ) modify(ls[k],x,y,v);else if( mid < x ) modify(rs[k],x,y,v);else {modify(ls[k],x,mid,v);modify(rs[k],mid+1,y,v);}update(k);
}
int query( int k, int x, int y ){pushdown(k);if( l[k] == x && r[k] == y ) return mx[k];int mid = (l[k]+r[k])>>1;if( mid >= y ) return query(ls[k],x,y);else if( mid < x ) return query(rs[k],x,y);else return max(query(ls[k],x,mid),query(rs[k],mid+1,y));
}
void solve_change( int x, int f, int v ){while( bel[x] != bel[f] ){change(root,pos[bel[x]],pos[x],v);x = anc[bel[x]][0];}if( pos[f]+1 <= pos[x] ) change(root,pos[f]+1,pos[x],v);
}
void solve_modify( int x, int f, int v ){while( bel[x] != bel[f] ){modify(root,pos[bel[x]],pos[x],v);x = anc[bel[x]][0];}if( pos[f]+1 <= pos[x] ) modify(root,pos[f]+1,pos[x],v);
}
int solve_query( int x, int f ){int res = -inf;while( bel[x] != bel[f] ){res = max(res,query(root,pos[bel[x]],pos[x]));x = anc[bel[x]][0];}if( pos[f]+1 <= pos[x] ) res = max(res,query(root,pos[f]+1,pos[x]));return res;
}
void dfs1( int x, int f ){siz[x] = 1;for( int p = 1; p <= 16; p++ )if( (1<<p) <= dep[x] ) anc[x][p] = anc[anc[x][p-1]][p-1];else break;for( int i = last[x]; i; i = e[i].next )if( e[i].to != f ){dep[e[i].to] = dep[x]+1;anc[e[i].to][0] = x;dfs1(e[i].to,x);siz[x] += siz[e[i].to];}
}
void dfs2( int x, int chain ){int k = 0; bel[x] = chain; pos[x] = ++sz;for( int i = last[x]; i; i = e[i].next )if( dep[e[i].to] > dep[x] ){if( siz[e[i].to] > siz[k] ) k = e[i].to;} else{ id[i>>1] = x; modify(1,pos[x],pos[x],e[i].v); }if( !k ) return; dfs2(k,chain);for( int i = last[x]; i; i = e[i].next )if( dep[e[i].to] > dep[x] && e[i].to != k ) dfs2(e[i].to,e[i].to);
}
int lca( int x, int y ){if( dep[x] < dep[y] ) swap(x,y);int t = dep[x]-dep[y];for( int p = 0; p <= 16; p++ ) if( (1<<p)&t ) x = anc[x][p];if( x == y ) return x;for( int p = 16; p >= 0; p-- ) if( anc[x][p] != anc[y][p] ) x = anc[x][p], y = anc[y][p];return anc[x][0];
}
int main(){scanf("%d", &n);for( int i = 1, u, v, w; i < n; i++ ) scanf("%d%d%d", &u, &v, &w), insert( u, v, w );build( root, 1, n ); dfs1(1,0); dfs2(1,1);while( 1 ){int u,v,w,f;scanf("%s", ch);switch(ch[1]){case 't':return 0;break;case 'd':scanf("%d%d%d",&u,&v,&w);f=lca(u,v); solve_modify(u,f,w);solve_modify(v,f,w);break;case 'o':scanf("%d%d%d",&u,&v,&w);f=lca(u,v); solve_change(u,f,w);solve_change(v,f,w);break;case 'h':scanf("%d%d",&u,&w);change(1,pos[id[u]],pos[id[u]],w);break;case 'a':scanf("%d%d",&u,&v);f=lca(u,v);printf("%d\n",max(solve_query(u,f),solve_query(v,f)));break;}}
}

[bzoj1984]月下“毛景树” 树链剖分相关推荐

  1. BZOJ1984: 月下“毛景树”

    BZOJ 1984: 月下"毛景树" Time Limit: 20 Sec  Memory Limit: 64 MB Submit: 1583  Solved: 500 [Subm ...

  2. [BZOJ1984] 月下“毛景树”

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

  3. 树剖+线段树||树链剖分||BZOJ1984||Luogu4315||月下“毛景树”

    题面:月下"毛景树" 题解:是道很裸的树剖,但处理的细节有点多(其实是自己线段树没学好).用一个Dfs把边权下移到点权,用E数组记录哪些边被用到了:前三个更新的操作都可以合并起来, ...

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

    题目链接: P4315 月下"毛景树" 大致题意 给定一棵由nnn个节点的树, 由n−1n - 1n−1带权边构成. 有如下444种操作: Change k c: 把第kkk条边的 ...

  5. 洛谷P4315 月下“毛景树” 题解

    洛谷P4315 月下"毛景树" 题解 题目链接:P4315 月下"毛景树" 题意:请维护一个数据结构,支持 改第 kkk 条边的边权 结点 uuu 到 vvv ...

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

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

  7. CodeForces - 1437G Death DBMS(AC自动机fail树上树链剖分建线段树/暴跳fail)

    题目链接:点击查看 题目大意:给出 n 个模式串,每个模式串初始时的权值为 0,然后有 m 次操作: 1 i x:将第 i 个模式串的权值修改为 x 2 s:给出一个字符串 s,询问字符串 s 作为主 ...

  8. 个人赛C 柠檬树2--树链剖分+维护最值出现次数/LCA

    给一棵树,维护上面两点最短路径中结点的最大值及最大值出现次数 #include <stdio.h> #include<string.h> #include<algorit ...

  9. bzoj 1984: 月下“毛景树” 线段树+树链剖分

    题意 给出一棵n个节点的树,每条边都有权值,要求资瓷以下操作: Max x y表示查询x到y之间的最大权值 Cover x y z表示把x到y的权值赋为z Change x y表示把第x条边的权值变成 ...

最新文章

  1. grub修复与grub.conf
  2. oracle 数据库,用户管理以及表空间等相关基础操作
  3. python3.4学习笔记(九) Python GUI桌面应用开发工具选择
  4. Java 中 @Autowired与@Resource的区别
  5. linux 5.5 外接usb2.0硬盘,RHEL5 使用pam_usb
  6. unity3d 挂载脚本_Unity3D加载资源的四种方式
  7. JUCE框架教程(3)—— Component ClassGraphics入门
  8. 用计算机程序计算鸡兔同笼,Linux脚本基础篇-鸡兔同笼问题(示例代码)
  9. Android 网易云信直播
  10. android触摸屏映射,解决android4.0 触摸屏分辨率映射不准
  11. 压测学习总结(1)——高并发性能指标:QPS、TPS、RT、吞吐量详解
  12. python实现RGB转换HSV
  13. 一一数落2006几大“恶心”事件
  14. Java之父求职被嫌年纪大:程序员只能吃青春饭?
  15. 网页简体转繁体的JS代码
  16. Android layer type与WebView白屏
  17. wuc-tab标签点击不了_买白酒时,不论啥牌子,只要标签上有“这行字”,全是酒精勾兑酒...
  18. 微博将于今日晚间挂牌上市 最高融资金额4.37亿美元
  19. MT7686芯片资料
  20. 40句让你坦露心声的句子

热门文章

  1. Byte 高位/低位简介绍(大端格式/小端格式)
  2. GPU价格暴跌,腾讯押注元宇宙,苹果在华招聘汽车人,今日更多大新闻在此
  3. IPv6的TSO/GRO/GSO及其Linux实现的不妥
  4. 【BugKu-CTF论坛writeup(杂项)】图穷匕见
  5. [转贴] Crystal和Oscillator的区别
  6. C#—MDI(多文档界面)
  7. ACM-ICPC 2018 焦作赛区网络预赛A. Magic Mirror(签到题)
  8. 五种知名的分布式数据库大PK
  9. matlab空间曲面拟合,【Matlab】离散点拟合曲面
  10. python语句print(0xa+0xb)_Python语句print(0xA+0xB)的输出结果为()