博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【luogu P4114 Qtree1】 题解
阅读量:5094 次
发布时间:2019-06-13

本文共 3916 字,大约阅读时间需要 13 分钟。

题目链接:

1.把边权转化到点权:选取连接这条边的两个点中较深的一个。
2.查询点到点之间的边权时,要从seg[x]+1 到 seg[y],因为seg[x]其实连接的是上面一条边的边权。

#include 
#include
#include
#include
#define ll long long#define lson left, mid, rt<<1#define rson mid + 1, right, rt<<1|1using namespace std;const ll maxn = 300000 + 10;char opt[9];ll n, m, root, res;ll top[maxn], rev[maxn], seg[maxn], son[maxn];ll fa[maxn], size[maxn], deep[maxn];ll u[maxn], v[maxn], w[maxn];ll tree[maxn<<2], lazy[maxn<<2], num, node[maxn];struct edge{ ll next, from, to, len;}e[maxn<<2];ll head[maxn], cnt;void add(ll u, ll v, ll w){ e[++cnt].from = u; e[cnt].len = w; e[cnt].next = head[u]; e[cnt].to = v; head[u] = cnt;}//-----segment_tree-----void PushUP(ll rt){ tree[rt] = max(tree[rt<<1], tree[rt<<1|1]);}void build(ll left, ll right, ll rt){ if(left == right) { tree[rt] = rev[left]; return; } ll mid = (left + right)>>1; build(lson); build(rson); PushUP(rt);}void PushDOWN(ll rt){ lazy[rt<<1] = lazy[rt]; lazy[rt<<1|1] = lazy[rt]; tree[rt<<1] = lazy[rt]; tree[rt<<1|1] = lazy[rt]; lazy[rt] = 0;}void update(ll l, ll r, ll add, ll left, ll right, ll rt){ if(l <= left && r >= right) { tree[rt] = add; lazy[rt] = add; return; } ll mid = (left + right)>>1; if(lazy[rt]) PushDOWN(rt); if(l <= mid) update(l, r, add, lson); if(r > mid) update(l, r, add, rson); PushUP(rt);}ll query(ll l, ll r, ll left, ll right, ll rt){ ll res = -0x7fffffff; if(l <= left && r >= right) { return tree[rt]; } ll mid = (left + right)>>1; if(lazy[rt]) PushDOWN(rt); if(l <= mid) res = max(res, query(l, r, lson)); if(r > mid) res = max(res, query(l, r, rson)); return res;}//----------------------void dfs1(ll u, ll f, ll d){ ll maxson = -1; size[u] = 1; deep[u] = d; fa[u] = f; for(ll i = head[u]; i != -1; i = e[i].next) { ll v = e[i].to; if(f != v) { dfs1(v, u, d+1); size[u] += size[v]; if(size[v] > maxson) son[u] = v, maxson = size[v]; } }}void dfs2(ll u, ll t){ seg[u] = ++num; rev[num] = node[u]; top[u] = t; if(!son[u]) return; dfs2(son[u], t); for(ll i = head[u]; i != -1; i = e[i].next) { ll v = e[i].to; if(v == son[u] || v == fa[u]) continue; dfs2(v,v); }}void updRange(ll x, ll y, ll k){ while(top[x] != top[y]) { if(deep[top[x]] < deep[top[y]]) swap(x, y); update(seg[top[x]], seg[x], k, 1, n, 1); x = fa[top[x]]; } if(deep[x] > deep[y]) swap(x, y); update(seg[x], seg[y], k, 1, n, 1);}ll qRange(ll x, ll y){ ll ans = 0; while(top[x] != top[y]) { if(deep[top[x]] < deep[top[y]]) swap(x, y); res = 0; res = query(seg[top[x]], seg[x], 1, n, 1); ans = max(res, ans); x = fa[top[x]]; } if(deep[x] > deep[y]) swap(x, y); res = 0; res = query(seg[x]+1, seg[y], 1, n, 1); ans = max(res, ans); return ans;}int main(){ memset(head, -1, sizeof(head)); scanf("%lld",&n); root = 1; for(ll i = 1; i < n; i++) { scanf("%lld%lld%lld",&u[i],&v[i],&w[i]); add(u[i],v[i],w[i]); add(v[i],u[i],w[i]); } dfs1(root, 0, 1); //for(int i = 1; i <= n; i++) cout<
<<" "; for(ll i = 1; i < n; i++) { if(deep[u[i]] < deep[v[i]]) node[v[i]] = w[i]; else node[u[i]] = w[i]; } //for(int i = 1; i <= n; i++) cout<
<<" "; dfs2(root, root); build(1, n, 1); while(cin>>opt && opt[0] != 'D') { ll x, y, z; if(opt[0] == 'C') { scanf("%lld%lld",&x,&y); if(deep[u[x]] > deep[v[x]]) updRange(u[x], u[x], y); else updRange(v[x], v[x], y); } else { scanf("%lld%lld",&x,&y); if(x == y) { printf("0\n"); continue; } printf("%lld\n",qRange(x,y)); } }}

转载于:https://www.cnblogs.com/MisakaAzusa/p/9416364.html

你可能感兴趣的文章
python asyncio 异步实现mongodb数据转xls文件
查看>>
TestNG入门
查看>>
【ul开发攻略】HTML5/CSS3菜单代码 阴影+发光+圆角
查看>>
IOS-图片操作集合
查看>>
IO—》Properties类&序列化流与反序列化流
查看>>
测试计划
查看>>
Mysql与Oracle 的对比
查看>>
jquery实现限制textarea输入字数
查看>>
Codeforces 719B Anatoly and Cockroaches
查看>>
c# 泛型+反射
查看>>
第九章 前后查找
查看>>
Python学习资料
查看>>
jQuery 自定义函数
查看>>
jquery datagrid 后台获取datatable处理成正确的json字符串
查看>>
ActiveMQ与spring整合
查看>>
web服务器
查看>>
第一阶段冲刺06
查看>>
EOS生产区块:解析插件producer_plugin
查看>>
JS取得绝对路径
查看>>
排球积分程序(三)——模型类的设计
查看>>