【COGS1672】难存的情缘
【题目描述】
一天机房的夜晚,无数人在MC里奋斗着。。。
大家都知道矿产对于MC来说是多么的重要,但由于矿越挖越少,勇士们不得不跑到更远的地方挖矿,但这样路途上就会花费相当大的时间,导致挖矿效率底下。
cjj提议修一条铁路,大家一致同意。
大家都被CH分配了一些任务:
zjmfrank2012负责绘制出一个矿道地图,这个地图包括家(当然这也是一个矿,毕竟不把家掏空我们是不会走的),和无数个矿,所以大家应该可以想出这是一个无向无环图,也就是一棵树。
Digital_T和cstdio负责铺铁路。。所以这里没他们什么事,两位可以劳作去了。
这个时候song526210932和RMB突然发现有的矿道会刷怪,并且怪的数量会发生变化。作为采矿主力,他们想知道从一个矿到另一个矿的路上哪一段会最困难。。。(困难值用zjm的死亡次数表示)。
【输入格式】
输入文件的第一行有一个整数N,代表矿的数量。矿的编号是1到N。
接下来N-1行每行有三个整数a,b,c,代表第i号矿和第j号矿之间有一条路,在初始时这条路的困难值为c。
接下来有若干行,每行是“CHANGE i ti”或者“QUERY a b”,前者代表把第i条路(路按所给顺序从1到M编号)的困难值修改为ti,后者代表查询a到b所经过的道路中的最大困难值。
输入数据以一行“DONE”结束。
【输出格式】
对每个“QUERY”操作,输出一行一个正整数,即最大困难值。
【分析】
实在是让人无语的背景改变,顺便膜拜一下梦迪神牛Orzzzzzzzz。
最基本的树链剖分。
#include <cstring>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <vector>
const int maxn=+;
using namespace std;
struct Edge
{
int to;//所指向的
int num;//记录边的编号
};
int d[maxn][],edge=,n,root;//用来记录边的属性
int siz[maxn],son[maxn];//子树大小和重儿子
int fa[maxn],dep[maxn],z;//父亲和深度
int w[maxn],top[maxn],tree[maxn];
char str[];
vector<Edge>map[maxn]; inline void init();
inline void work();
inline void dfs(int u);//第一次DFS
inline void addEdge(int u,int v);//加边
inline void make_tree(int u,int tp);//第二次DFS
inline void update(int root,int l,int r,int num,int c);//c是变更值
inline int read();//读入函数
inline int find(int a,int b);
inline int maxi(int root,int l,int r,int l1,int l2); inline void addEdge(int u,int v)
{
edge++;
map[u].push_back((Edge){v,edge});
}
inline void dfs(int u)//第一次dfs
{
int i;
siz[u]=;
son[u]=;
for (i=;i<map[u].size();i++)
{
int v=map[u][i].to;
if (v!=fa[u])
{
fa[v]=u;//更新父亲
dep[v]=dep[u]+;//更新深度
dfs(v);
if (siz[v]>siz[son[u]]) son[u]=v;
siz[u]+=siz[v];
}
}
}
//建树操作
inline void make_tree(int u,int tp)
{
int i;
w[u]=++z;
top[u]=tp;
if (son[u]!=) make_tree(son[u],top[u]);//优先走重儿子
for (i=;i<map[u].size();i++)
{
int v=map[u][i].to;
if (v!=son[u] && v!=fa[u])
make_tree(v,v);
}
}
//修改操作
inline void update(int root,int l,int r,int num,int c)
{
if (num>r || num<l) return;
if (l==r) {tree[root]=c;return;}
int mid=(l+r)/;
//递归修改
update(root*,l,mid,num,c);
update(root*+,mid+,r,num,c);
tree[root]=max(tree[root*],tree[root*+]);
}
inline void init()
{
int i;
scanf("%d",&n);
root=(+n)/;//随机根
fa[root]=z=dep[root]=edge=;
memset(d,,sizeof(d));
memset(tree,,sizeof(tree));
for (i=;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
d[i][]=u;d[i][]=v;d[i][]=w;
addEdge(u,v);//加无向边
addEdge(v,u);
}
dfs(root);//第一次
make_tree(root,root);
for (i=;i<n;i++)
{
if (dep[d[i][]]>dep[d[i][]]) swap(d[i][],d[i][]);//交换
update(,,z,w[d[i][]],d[i][]);//开始加边
}
return;
}
inline int read()
{
scanf("%s",str);
if (str[]=='D')
return ;
//printf("%s\n",str);
return ;
}
inline int maxi(int root,int l,int r,int l1,int r1)
{
if (l1>r || r1<l) return ;//边界条件
if (l1<=l && r<=r1) return tree[root];
int mid=(l+r)/;
return max(maxi(root*,l,mid,l1,r1),maxi(root*+,mid+,r,l1,r1));
}
//进行从a到b的询问
inline int find(int a,int b)
{
int f1=top[a],f2=top[b],temp=;
while (f1!=f2)//LCA
{
if (dep[f1]<dep[f2])//统一深度
{
swap(f1,f2);
swap(a,b);
}
temp=max(temp,maxi(,,z,w[f1],w[a]));
a=fa[f1];f1=top[a];//向上传递
}
if (a==b) return temp;
if (dep[a]>dep[b]) swap(a,b);
return max(temp,maxi(,,z,w[son[a]],w[b]));
}
inline void work()
{
int a,b;
while (read())
{
scanf("%d%d",&a,&b);
if (str[]=='Q') printf("%d\n",find(a,b));
else update(,,z,w[d[a][]],b);
}
return;
}
int main()
{
//文件操作
freopen("qtree.in","r",stdin);
freopen("qtree.out","w",stdout);
init();//初始化
work();
return ;
}
【COGS1672】难存的情缘的更多相关文章
- Cogs 1672. [SPOJ375 QTREE]难存的情缘 LCT,树链剖分,填坑计划
题目:http://cojs.tk/cogs/problem/problem.php?pid=1672 1672. [SPOJ375 QTREE]难存的情缘 ★★★☆ 输入文件:qtree.in ...
- OI总结(垃圾排版就忽略了吧)
学OI一年了,到现在联赛所需要的知识已经基本学完了.现在,有必要回过头来,总结总结自己一年来学到的知识以及得到的经验教训. 基础 语言基础 C++的语言基础啥的就略了吧. 算法复杂度分析 O:复杂度的 ...
- 染色[SDOI2011]
题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如"11 ...
- 「专题总结」LCT入门
上次xuefeng说我的专题总结(初探插头dp)太不适合入门了,所以这次丢一些题解包以外的东西. 关键是我自己也不会...急需梳理一下思路... (让我口胡数据结构???顺便推广一下全世界最短的lct ...
- 「LCT」
终于在多篇题解和我的个人超常发挥下抄完了lct的所有题,kx死了. 理解 在我看来,实际上lct的板子没有什么考的,更重要的可能是起到一个数据结构的维护作用实际上就是出题人想给你找点乐子. 前几道题都 ...
- CodeIgniter(CI)框架中的验证码
在CodeIgniter框架中,CI本身自带了验证码,但是查看文档的时候,发现: 需要新建一个表,用来存储验证码信息.因为习惯了session存储验证码信息,所以我把我认为比较好看的验证码应用在了CI ...
- php表单数据验证类
非常好用方便的表单数据验证类 <?php //验证类 class Fun{ function isEmpty($val) { if (!is_string($val)) return false ...
- 历代诗词咏宁夏注释2_----苍岩道人<登文昌阁>
登文昌阁[1] 苍岩道人 壮年碌碌走尘埃,此地清幽不肯来. 老去始惊春梦促,韶光易过槿花开.[2] 历朝兴废书千卷,万古忠奸土一堆.[3] 惟爱莎罗歌最好,闲时拍板满斟杯.[4] 注释 [说明]选自& ...
- ThinkPHP/Common/extend.php
<?php // +---------------------------------------------------------------------- // | ThinkPHP [ ...
随机推荐
- WallsEveryDay 必应桌面壁纸
软件名:WallsEveryday 陈述: 无聊时写着玩的一个桌面壁纸的软件,壁纸是自动从必应下载,所以每天都会有新的. 在ubuntu上测试通过,windows上找了台win7测试通过,其他没测试. ...
- 暴力求解——除法 Division,UVa 725
Description Write a program that finds and displays all pairs of 5-digit numbers that between them u ...
- Velocity常用方法
1.字符串替换 replace#if($!{name} != '')#set($tempName = $!{name})#set($tempName = $tempName.Replace('abc' ...
- uoj#67. 新年的毒瘤(割顶)
#67. 新年的毒瘤 辞旧迎新之际,喜羊羊正在打理羊村的绿化带,然后他发现了一棵长着毒瘤的树. 这个长着毒瘤的树可以用n个结点m 条无向边的无向图表示.这个图中有一些结点被称作是毒瘤结点,即删掉这个结 ...
- Miller-Rabin质数测试
Miller-Rabin质数测试 本文主要讨论使用Miller-Rabin算法编写素数的判定算法,题目来源于hihocoder. 题目 题目要求 时间限制:10000ms 单点时限:1000ms 内存 ...
- JVM 调优
JVM内存,由三个部分构成 年轻代+老年代+永久代: 需要调试的是年轻代和老年代 的参数: 先解释几个JVM参数: -XMx : 最大可用内存: -Xms:初始化内存: -xss: 线程栈 的大小: ...
- "org.eclipse.wst.validation" has been removed
导出maven工程遇到的问题,"org.eclipse.wst.validation" has been removed,还以为是工程本身的问题,后来发现是eclipse的问题. ...
- 狗血phonegap备忘录[3.3]
phonegap平台就是个狗血的坑,最近的一个项目技术因为上面选型失败,使用了phonegap,加上客户的要求是"像微信一样",真可谓历经坎坷. 基本上评估一个项目是否应该或者可以 ...
- 谋哥:App自推广这个概念就由我来创立了!
[谋哥每天一干货,第六十四篇] 昨天谋天团新增加了一名90后会员崔崔(微信号cuinianyyyy9),之前请教过我关于怎样从.Net到移动IOS开发然后创业的问题.我说你转到IOS,你须要自己学新语 ...
- [Angular 2] Using Pipes to Filter Data
Pipes allow you to change data inside of templates without having to worry about changing it in the ...