SPOJ 375 树链剖分
SPOJ太慢了,SPOJ太慢了,
题意:给定n(n<=10000)个节点的树,每条边有边权,有两种操作:1.修改某条变的边权;2.查询u,v之间路径上的最大边权。
分析:树链剖分入门题,看这里:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html
轻重链剖分,线段树维护,复杂度 O(nlogn + q* logn * logn )
SPOJ太慢了,我知道我写的应该是没错了,
最后把自己宏定义的max和min去掉之后终于过了,傻逼笑呵呵了。。为啥宏定义max,min占用这么长时间,求指教。
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
#define maxn 10010 int w[maxn],son[maxn],sz[maxn],top[maxn],fa[maxn],dep[maxn];
int d1[maxn][];
int z;
int n ;
char str[];
struct node
{
int v ,next;
}; node e[maxn * ];
int cnt ;
int head[maxn];
int tt[maxn * ]; inline void add(int u ,int v)
{
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt ++ ;
return ;
}
void push_up(int root )
{
tt[root] = max(tt[root*],tt[root*+]);
}
inline void dfs1(int u ) // 计算 sz[],son[],dep[],fa[];
{
sz[u] = ;
son[u] = ;
for(int i = head[u] ; i != - ; i = e[i].next)
if(e[i].v != fa[u])
{
fa[e[i].v] = u;
dep[e[i].v] = dep[u] + ;
dfs1(e[i].v);
if(sz[e[i].v] > sz[son[u]] ) son[u] = e[i].v;
sz[u] += sz[e[i].v];
}
} void dfs2(int u,int tp) // 计算 w[],top[]
{
w[u] = ++ z ;
top[u] = tp;
if(son[u] != ) dfs2(son[u] , top[u]);
for(int i = head[u] ; i!= - ;i = e[i].next)
if(e[i].v != fa[u] && e[i].v != son[u] )
dfs2(e[i].v,e[i].v);
return ;
}
void update(int root,int l,int r,int pos,int val)
{
if(l == r )
{
tt[root] = val;
return ;
}
int mid = (l + r ) / ;
if(pos <= mid)
update(root + root ,l,mid, pos , val);
else
update(root + root + ,mid + , r , pos ,val);
push_up(root);
return ;
}
int query(int root,int l1,int r1,int l,int r)
{
if(l <= l1 && r1 <= r)
return tt[root];
int mid = (l1 + r1 ) / ;
int res = ;
if(l <= mid )
res = max(res , query(root + root,l1 , mid , l , r ));
if(r > mid )
res = max(res , query(root + root + ,mid + , r1 , l , r ));
return res;
}
int find(int a,int b)
{
int f1 = top[a] , f2 = top[b] , tmp = ;
while( f1 != f2 )
{
if(dep[f1] < dep[f2])
swap(f1,f2),swap(a,b);
tmp = max(tmp , query(,,z,w[f1],w[a]) );
a = fa[f1],f1 = top[a];
}
if(a == b) return tmp ;
if(dep[a] > dep[b]) swap(a,b);
return max(tmp , query(,,z,w[son[a]],w[b]) ); // 父边
} int main()
{
int root;
int u,v,w1;
int cas;
scanf("%d",&cas);
while(cas -- )
{
scanf("%d",&n);
cnt = ;
memset(head,-,sizeof(head));
memset(tt,,sizeof(tt));
for(int i = ; i < n ; i ++ )
{
scanf("%d%d%d",&u,&v,&w1);
d1[i][] = u;
d1[i][] = v;
d1[i][] = w1;
add(u,v);
add(v,u);
}
root = ;
dep[root] = ;
fa[root] = ;
dfs1(root);
z = ;
dfs2(root,root);
for(int i = ; i < n ; i ++ )
{
if(dep[d1[i][]] > dep[d1[i][]] ) swap(d1[i][],d1[i][]);
update(,,z,w[d1[i][]] ,d1[i][]);
}
scanf("%s",str);
while(str[] != 'D')
{
scanf("%d%d",&u,&v);
if(str[] == 'Q')
printf("%d\n",find(u,v));
else update(,,z,w[d1[u][]],v);
scanf("%s",str);
}
}
return ;
}
/*
tle
建树费时删去->tle
// luangao -> tle
去掉自己宏定义的max和min -> AC!!!!!!!!!!!!
*/
据说这题还可用link_cut tree做,论文没看懂。。。
看这里 QTREE解法的一些研究
这类问题是动态树问题:算法合集之《动态树问题及其应用》 ,也没看懂。。。。
SPOJ 375 树链剖分的更多相关文章
- SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I 给你一棵有边权的树,有两个操作:一个操作是输出l到 ...
- SPOJ 375 (树链剖分+线段树)
题意:一棵包含N 个结点的树,每条边都有一个权值,要求模拟两种操作:(1)改变某条边的权值,(2)询问U,V 之间的路径中权值最大的边. 思路:最近比赛总是看到有树链剖分的题目,就看了论文,做了这题, ...
- SPOJ 375 树链剖分 QTREE - Query on a tree
人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...
- spoj 375 树链剖分模板
/* 只是一道树链刨分的入门题,作为模板用. */ #include<stdio.h> #include<string.h> #include<iostream> ...
- spoj 375 树链剖分 模板
QTREE - Query on a tree #tree You are given a tree (an acyclic undirected connected graph) with N no ...
- SPOJ QTREE 树链剖分
树链剖分的第一题,易懂,注意这里是边. #include<queue> #include<stack> #include<cmath> #include<cs ...
- 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, ...
- 【学术篇】SPOJ QTREE 树链剖分
发现链剖这东西好久不写想一遍写对是有难度的.. 果然是熟能生巧吧.. WC的dalao们都回来了 然后就用WC的毒瘤题荼毒了我们一波, 本来想打个T1 44分暴力 然后好像是特判写挂了还是怎么的就只能 ...
- spoj 375 Query on a tree(树链剖分,线段树)
Query on a tree Time Limit: 851MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Sub ...
随机推荐
- Basic脚本解释器移植到STM32
本文来自http://blog.csdn.net/hellogv/ .引用必须注明出处! 上次讲了LUA移植到STM32.这次讲讲Basic脚本解释器移植到STM32. 在STM32上跑Basic脚本 ...
- MVC Razor标签
1. RenderBody在Razor引擎中没有了“母版页”,取而代之的是叫做“布局”的页面(_Layout.cshtml)放在了共享视图文件夹中.在这个页面中,会看到标签里有这样一条语句:@Rend ...
- selinux 工具下载地址
http://userspace.selinuxproject.org/releases/ 里面包含了 Name Last modified Size Description Parent Direc ...
- 【原创】leetCodeOj --- Merge k Sorted Lists 解题报告
题目地址: https://oj.leetcode.com/problems/merge-k-sorted-lists/ 题目内容: /** * Definition for singly-linke ...
- 使用BackgroundWorker组件进行异步操作编程
本文介绍了BackgroundWorker组件的功能及在基于事件的异步操作编程中的应用,并对组件的实现原理进行简述.在应用程序中,可能会遇到一些执行耗时的功能操作,比如数据下载.复杂计算及数据库事务等 ...
- 华为编程大赛汇总----java
以下华为编程比赛题目都是网上整理得到的,代码都是自己调试过的,由于网上java答案较少,欢迎大家批评指正,也希望对准备华为上机的童鞋们有一点点帮助.在练习的过程中成长,加油!~~ 1. ...
- Myeclipse它显示了一个目录的结构,而不是包
今天Myeclipse新project,编写代码,查找workspace空间展示project在包装和class所有平行结构,看的很不顺,有两个原因,第一,您可能无法切换到Package worksp ...
- Android client和服务器JSP互传中国
出于兼容性简化.传统中国等多国语言.推荐使用UTF-8编码. 首选.我们期待Android到底应该怎么办: 在发送前,应该对參数值要进行UTF-8编码,我写了一个static的 转换函数.在做发送动作 ...
- android 视频通话开启呼叫等待后,来第三方的视频通话,接通后通话时间一直显示为0,过几秒之后视频通话自己主动挂断
开启通话设置视频通话的"来电等待"; 步骤1:測试机和配合机A处于视频通话过程中; 步骤2:配合机B向測试机呼出视频电话; 步骤3:測试机接听配合机B的视频来电; 现象:视频通话过 ...
- .NET MVC学习笔记(一)
看了些关于MVC的资料,做一些MVC的笔记. 分解关注点 在MVC世界里有个很重要的观念--"分解关注点"(Separation of Concerns),指的是:当你进行软件开发 ...