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 树链剖分的更多相关文章

  1. SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I 给你一棵有边权的树,有两个操作:一个操作是输出l到 ...

  2. SPOJ 375 (树链剖分+线段树)

    题意:一棵包含N 个结点的树,每条边都有一个权值,要求模拟两种操作:(1)改变某条边的权值,(2)询问U,V 之间的路径中权值最大的边. 思路:最近比赛总是看到有树链剖分的题目,就看了论文,做了这题, ...

  3. SPOJ 375 树链剖分 QTREE - Query on a tree

    人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...

  4. spoj 375 树链剖分模板

    /* 只是一道树链刨分的入门题,作为模板用. */ #include<stdio.h> #include<string.h> #include<iostream> ...

  5. spoj 375 树链剖分 模板

    QTREE - Query on a tree #tree You are given a tree (an acyclic undirected connected graph) with N no ...

  6. SPOJ QTREE 树链剖分

    树链剖分的第一题,易懂,注意这里是边. #include<queue> #include<stack> #include<cmath> #include<cs ...

  7. 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, ...

  8. 【学术篇】SPOJ QTREE 树链剖分

    发现链剖这东西好久不写想一遍写对是有难度的.. 果然是熟能生巧吧.. WC的dalao们都回来了 然后就用WC的毒瘤题荼毒了我们一波, 本来想打个T1 44分暴力 然后好像是特判写挂了还是怎么的就只能 ...

  9. spoj 375 Query on a tree(树链剖分,线段树)

      Query on a tree Time Limit: 851MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Sub ...

随机推荐

  1. Codeforces Round #257 (Div. 2) 题解

    Problem A A. Jzzhu and Children time limit per test 1 second memory limit per test 256 megabytes inp ...

  2. LeetCode 53 Spiral Matrix

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...

  3. 一个简单的带缓存http代理

    眼下1.0版模型非常easy.即对客户机发来的请求进行简单处理后,转发到server.转发之前先检查本地缓存.假设有.则直接回送给客户本地资源 程序流程大致例如以下图: 缓存是通过把文件保存到磁盘上, ...

  4. 由单页面web应用引发的企业应用问题

    由于单页面web应用的流行,client与server端之间都对应的产生了一些微妙的变化,比方,client原来仅仅是用来展示页面和理清逻辑,而现在逐渐转变成了一个可以进入驱动状态的应用程序. 未来的 ...

  5. C++ 习题 输出日期时间--友元函数

    Description 设计一个日期类和时间类,编写display函数用于显示日期和时间.要求:display函数作为类外的普通函数,分别在Time和Date类中将display声明为友元函数.在主函 ...

  6. 《数据结构、算法及应用》9.(C++实施订单)

    最近阅读<数据结构.算法及应用>这本书,书中的习题汇总,用自己的方法来实现这些问题.可能效率.等方面存在着非常多的问题,也可能是错误的实现.假设大家在看这本书的时候有更优更好的方法来实现, ...

  7. poj 2182 Lost Cows(段树精英赛的冠军)

    主题链接:http://poj.org/problem? id=2182 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  8. Codeforces 474 E. Pillars

    水太...... E. Pillars time limit per test 1 second memory limit per test 256 megabytes input standard ...

  9. TI C66x DSP 系统events及其应用 - 5.8(ISTP)

    中断服务表指针ISTP(Interrupt Service Table Pointer)位置寄存器用于定位的中断服务例程,那ISTP去哪里找要运行的程序,ISTP(当中的ISTB字段)就是指向IST表 ...

  10. iOS 7 新特性

      iOS7更新了很多引人注目的功能.用户界面完全重新设计了.iOS7为开发2D,2.5D游戏引入了全新的动画系统.加强多线程,点对点连接,以及许多其他重要的功能让iOS7成为有史以来最有意义的一次发 ...