【题目描述】

一天机房的夜晚,无数人在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】难存的情缘的更多相关文章

  1. Cogs 1672. [SPOJ375 QTREE]难存的情缘 LCT,树链剖分,填坑计划

    题目:http://cojs.tk/cogs/problem/problem.php?pid=1672 1672. [SPOJ375 QTREE]难存的情缘 ★★★☆   输入文件:qtree.in  ...

  2. OI总结(垃圾排版就忽略了吧)

    学OI一年了,到现在联赛所需要的知识已经基本学完了.现在,有必要回过头来,总结总结自己一年来学到的知识以及得到的经验教训. 基础 语言基础 C++的语言基础啥的就略了吧. 算法复杂度分析 O:复杂度的 ...

  3. 染色[SDOI2011]

    题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如"11 ...

  4. 「专题总结」LCT入门

    上次xuefeng说我的专题总结(初探插头dp)太不适合入门了,所以这次丢一些题解包以外的东西. 关键是我自己也不会...急需梳理一下思路... (让我口胡数据结构???顺便推广一下全世界最短的lct ...

  5. 「LCT」

    终于在多篇题解和我的个人超常发挥下抄完了lct的所有题,kx死了. 理解 在我看来,实际上lct的板子没有什么考的,更重要的可能是起到一个数据结构的维护作用实际上就是出题人想给你找点乐子. 前几道题都 ...

  6. CodeIgniter(CI)框架中的验证码

    在CodeIgniter框架中,CI本身自带了验证码,但是查看文档的时候,发现: 需要新建一个表,用来存储验证码信息.因为习惯了session存储验证码信息,所以我把我认为比较好看的验证码应用在了CI ...

  7. php表单数据验证类

    非常好用方便的表单数据验证类 <?php //验证类 class Fun{ function isEmpty($val) { if (!is_string($val)) return false ...

  8. 历代诗词咏宁夏注释2_----苍岩道人<登文昌阁>

    登文昌阁[1] 苍岩道人 壮年碌碌走尘埃,此地清幽不肯来. 老去始惊春梦促,韶光易过槿花开.[2] 历朝兴废书千卷,万古忠奸土一堆.[3] 惟爱莎罗歌最好,闲时拍板满斟杯.[4] 注释 [说明]选自& ...

  9. ThinkPHP/Common/extend.php

    <?php // +---------------------------------------------------------------------- // | ThinkPHP [ ...

随机推荐

  1. Ehcache中配置详解

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLoc ...

  2. BZOJ 1072 [SCOI2007]排列perm

    1072: [SCOI2007]排列perm Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1268  Solved: 782[Submit][Sta ...

  3. javascript 基础学习整理

    1. javascript是动态语言,脚本语言,弱类型语言. 2. javascript代码在html文件中的位置安排,放在<body></body>内部与外部的区别.如何引用 ...

  4. (转载)用PHP正则表达式清除字符串的空白

    (转载)http://www.chinaz.com/program/2009/0220/67569.shtml 我们经常会处理来自用户输入或从数据库中读取的数据,可能在你的字符串中有多余的空白或制表符 ...

  5. UNITY3D ShadeSH9

    UNITY3D ShadeSH9 属于Irradiance environment maps 方法,可以参考DX SDK PRTDemo,里面是几乎相同的实现,总之就是解光传输的积分方程 目前主流辐射 ...

  6. 意大利进口的衬衫面料pH值严重超标·都市快报

    意大利进口的衬衫面料pH值严重超标·都市快报     意大利进口的衬衫面料pH值严重超标         董捷    2007-03-24           通讯员 浙 检 记 者 董 捷      ...

  7. DNA Sequence - POJ 2778(AC自动机+矩阵乘法)

    题目大意:DNA序列是有 ATGC 组成的,现在知道一些动物的遗传片段有害的,那么如果给出这些有害的片段,能否求出来所有长度为 N 的基因中有多少是不包含这些有害片段的.   分析:也是断断续续做了一 ...

  8. I - Arbitrage

    题目大意:套汇 套利是使用货币汇率的差异将一个单位的货币转换为多个相同的货币单位,例如1美元可以买0.5英镑,1英镑可以买10法郎,1法郎可以买0.21美元,然后聪明的人经过一些列兑换可以得到 1*0 ...

  9. Java 自动装箱和拆箱

    JDK1.5之后的功能 自动装箱:指的是开发人员可以把一个基本数据类型直接赋给对应的包装类 自动拆箱:指开发人员可以把一个包装类对象直接赋给对应的基本数据类型 public static void m ...

  10. linux —— 学习笔记(软件操作:安装、卸载、执行)

    目录: 0.相关基本命令    1.安装软件    2.卸载软件    3.打开软件  0.相关基本命令 与软件操作相关的主要命令有:dpkg  和 apt-get . dpkg   : “dpkg ...