SPOJ QTREE Query on a tree ——树链剖分 线段树
【题目分析】
垃圾vjudge又挂了。
树链剖分裸题。
垃圾spoj,交了好几次,基本没改动却过了。
【代码】(自带常数,是别人的2倍左右)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 20005 int T,n,fr[maxn],h[maxn],to[maxn],ne[maxn],w[maxn],en=0;
int mx[maxn<<3],fa[maxn],siz[maxn],son[maxn],pos[maxn],dep[maxn],tot=0;
int top[maxn],a[maxn],x,y,L,R,C,X,tofa[maxn];
char opt[10]; int Getint()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
} void add(int a,int b,int c)
{fr[en]=a;to[en]=b;ne[en]=h[a];w[en]=c;h[a]=en++;} void rd()
{
n=Getint();
for(register int i=1;i<n;++i)
{
int a=Getint(),b=Getint(),c=Getint();
add(a,b,c),add(b,a,c);
}
}
void init()
{
memset(fa,0,sizeof fa);
memset(son,0,sizeof son);
memset(h,-1,sizeof h);
tot=en=0;
} void dfs1(int o)
{
siz[o]=1;
for (register int i=h[o];i>=0;i=ne[i])
if (fa[o]!=to[i]){
fa[to[i]]=o;
tofa[to[i]]=w[i];
dep[to[i]]=dep[o]+1;
dfs1(to[i]);
siz[o]+=siz[to[i]];
if (siz[son[o]]<siz[to[i]]) son[o]=to[i];
}
} void dfs2(int o,int tp,int ww)
{
// printf("dfs2 _ %d %d %d son is %d\n",o,tp,ww,son[o]);
top[o]=tp;pos[o]=++tot;a[pos[o]]=ww;
if (son[o]==0) return;
// for (register int i=h[o];i>=0;i=ne[i])
// if (to[i]==son[o])
// dfs2(son[o],tp,w[i]);
// printf("%d to %d as height son\n",o,son[o]);
dfs2(son[o],tp,tofa[son[o]]);
for (register int i=h[o];i>=0;i=ne[i])
if (fa[o]!=to[i]&&to[i]!=son[o])
dfs2(to[i],to[i],w[i]);
} void build(int o,int l,int r)
{
int mid=l+r>>1;
if (l==r){mx[o]=a[l];return;}
build(o<<1,l,mid); build(o<<1|1,mid+1,r);
mx[o]=max(mx[o<<1],mx[o<<1|1]);
} void modify(int o,int l,int r)
{
if (l==r) {mx[o]=C;return;}
int mid=l+r>>1;
if (X<=mid) modify(o<<1,l,mid);
else modify(o<<1|1,mid+1,r);
mx[o]=max(mx[o<<1],mx[o<<1|1]);
} int query(int o,int l,int r)
{
if (L<=l&&r<=R) return mx[o];
int mid=l+r>>1;
if (R<=mid) return query(o<<1,l,mid);
if (L>mid) return query(o<<1|1,mid+1,r);
else return max(query(o<<1,l,mid),query(o<<1|1,mid+1,r));
} int ask(int x,int y)
{
int ret=0;
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
L=pos[top[x]];R=pos[x];
ret=max(ret,query(1,1,n));
x=fa[top[x]];
}
if (dep[x]<dep[y]) swap(x,y);
if (x==y) return ret;
L=pos[son[y]];R=pos[x];
ret=max(ret,query(1,1,n));
return ret;
} int main()
{
freopen("in.txt","r",stdin);
freopen("wa.txt","w",stdout);
T=Getint();
while (T--)
{
init(),rd();
dfs1(1);dfs2(1,1,0);
// printf("n is %d\n",n);
build(1,1,n);
while (scanf("%s",opt)&&opt[0]!='D')
{
if (opt[0]=='Q')
{
x=Getint();y=Getint();
printf("%d\n",ask(x,y));
}
else
{
x=Getint(); y=Getint();
L=fr[x*2-1];R=to[x*2-1];
if (fa[L]==R) X=pos[L],C=y,modify(1,1,n);
else X=pos[R],C=y,modify(1,1,n);
}
}
}
return 0;
}
SPOJ QTREE Query on a tree ——树链剖分 线段树的更多相关文章
- Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- POJ3237 Tree 树链剖分 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...
- 【CF725G】Messages on a Tree 树链剖分+线段树
[CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...
- Water Tree CodeForces 343D 树链剖分+线段树
Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组
Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...
随机推荐
- socket使用非阻塞connect
在使用tcp的connect调用时,默认是使用阻塞方式,当服务器当前不可用时,connect会等待(内部在重试?)直到超时时间到达,而这个超时时间是系统内核规定的,不能使用setSocketOpt来设 ...
- JMeter3.2入门使用教程
JMeter3.2入门使用教程 背景说明 1.1. 背景简介 JMeter是Apache软件基金会下的一个开源项目,纯java开发的应用工具,可以作为进行负载和压力测试的工具来使用.从最开始时被设计成 ...
- ios push Payload
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotifi ...
- c#写出乘法口诀
显然是显得无聊五分钟写的乘法口诀 static void Main(string[] args) { int dq; int[] array ...
- fossil 代理设置
C:\>fossil user new Joe C:\>fossil user default Joe 设置账户 fossil setting proxy http://-:-fossil ...
- applicationContext.xml重要配置
<!-- 加载 hibernate.properties 文件--> <bean id="propertyConfig" class="org.spri ...
- x220 OS X 10.10.4安装
变色龙安装过程: 1.使用磁盘助手将按照盘写入独立的磁盘分区(AF格式,就是Apple的HPS格式): 2.安装启动时,用-v -f -x参数,分别为显示信息.重新build系统驱动.安全模式: 3. ...
- C++笔记(仅C++特性,需C语言基础)
C++复习笔记一(类的声明定义应用与构造函数析构函数部分)const在C语言中是"不能被改变值的变量",而在C++种子则是"一种有类型描述的常量",常量必须初始 ...
- PAT 乙级 1005
题目 题目地址:PAT 乙级 1005 题解 本题主要就在于将一个数的一系列计算结果不重复地存储起来并便于检索,考虑到STL中的集合有相似的特性,使用set可以有效地简化代码和运算. 过程如下: (初 ...
- mysql中常用函数简介(不定时更新)
常用函数version() 显示当前数据库版本database() 返回当前数据库名称user() 返回当前登录用户名inet_aton(IP) 返回IP地址的数值形式,为IP地址的数学计算做准备in ...