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 ...
随机推荐
- C++习题 复数类--重载运算符+
Description 定义一个复数类Complex,重载运算符"+",使之能用于复数的加法运算.将运算符函数重载为非成员.非友元的普通函数.编写程序,求两个复数之和. Input ...
- 使用QT 4.8.6 + Cmake 3.0.0 编译 最新版本OpenCv3.0.0
mingw32 (x32) gcc g++ qt opencv- -- cmake -rc1 windows x64 参考文章: http://blog.csdn.net/qiurisuixiang/ ...
- FTP文件操作之删除文件
上面我已经介绍了利用ftp进行上传跟下载,接下来跟大家分享的是删除ftp服务器上的文件的部分.有了上传,有了下载,那么删除自然也是不能少的. 删除相对于上传跟下载更简单一些,它不需要进行文件的传输,只 ...
- 得知Android小遴选程序第七头(他们定义对话框、Gallery、ImageSwitcher)
效果如下面的: 一共一个activity和两个xml. ******当我们须要使用的组件不在setContentView()设置的布局文件里,那我们就须要使用inflate()方 ...
- iOS的图表显示的实现
在app通常有家居展览的照片,显示广告.或者头条新闻.通常网易新闻client 如图,红框框的位置就是一个典型的图展, 熟悉iOS的人肯定知道,这个是个UIScrollview,里面加几张图片就可以实 ...
- IntelliJ 15 unmapped spring configuration files found
IntelliJ Spring Configuration Check 用IntelliJ 导入现有工程时,如果原来的工程中有spring,每次打开工程就会提示:Spring Configuratio ...
- hdu3790最短路径问题
题意是这种,给你一个无向图, 每条边有距离和花费, 假设从第一个点到末点的最短路不唯一, 则输出最短路长度以及最少的花费. 否则输出长度和花费即可. 用传说中的链式向前星优化了一下边的存储, 写了个s ...
- C#的WebBrowser控制浏览
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Android-管理Activity生命周期
用户在浏览,退出,返回app时,app中的Activity实例会在不同状态之间切换.比如,当activity第一次启动,然后来到系统前台,受到用户的注意,这个过程中,android系统调用了一系列ac ...
- Xcode 6 AutoLayout Size Classes
1.基本概念 在iPad和iPhone 5出现之前,iOS设备就唯独一种尺寸. 我们在做屏幕适配时须要考虑的唯独设备方向而已. 而非常多应用并不支持转向,这种话就全然没有屏幕适配的工作了. 随着iPa ...