poj 3237 Tree [LCA] (树链剖分)
inline :
1. inline 定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高。
2. 很明显,类的内联函数也是一个真正的函数,编译器在调用一个内联函数时,会首先检查它的参数的类型,保证调用正确。然后进行一系列的相关检查,就像对待任何一个真正的函数一样。这样就消除了它的隐患和局限性。
3. inline 可以作为某个类的成员函数,当然就可以在其中使用所在类的保护成员及私有成员。
在何时使用inline函数:
首先,你可以使用inline函数完全取代表达式形式的宏定义。
另外要注意,内联函数一般只会用在函数内容非常简单的时候,这是因为,内联函数的代码会在任何调用它的地方展开,如果函数太复杂,代码膨胀带来的恶果很可能会大于效率的提高带来的益处。内联函数最重要的使用地方是用于类的存取函数。

view code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N = 10010;
const int INF = 1<<30;
int _, n, pre[N], fa[N], sz[N], top[N];
int gid, dep[N], son[N], id[N], fid[N];
int Max[N<<2], Min[N<<2], neg[N<<2]; struct edge
{
int u, v, w, next;
edge() {}
edge(int u, int v,int w, int next):u(u),v(v),w(w),next(next) {}
}e[N<<1];
int ecnt; inline void addedge(int u, int v, int w)
{
e[ecnt] = edge(u, v, w, pre[u]);
pre[u] = ecnt++;
e[ecnt] = edge(v, u, w, pre[v]);
pre[v] = ecnt++;
} inline void dfs(int u, int f, int d)
{
sz[u]=1, fa[u]=f, dep[u]=d, son[u]=0;
for(int i=pre[u]; ~i; i=e[i].next)
{
int v = e[i].v;
if(v==f) continue;
dfs(v, u, d+1);
sz[u] += sz[v];
if(sz[son[u]]<sz[v]) son[u] = v;
}
} inline void fxor(int &x)
{
x = x==INF?-INF:INF;
} inline void getpos(int u, int f)
{
id[u] = ++gid;
fid[gid] = u;
top[u] = f;
if(son[u]==0) return ;
getpos(son[u], f);
for(int i=pre[u]; ~i; i=e[i].next)
{
int v = e[i].v;
if(v==fa[u] || v==son[u]) continue;
getpos(v, v);
}
} inline void Up(int rt)
{
Max[rt] = max(Max[rt<<1], Max[rt<<1|1]);
Min[rt] = min(Min[rt<<1], Min[rt<<1|1]);
} inline void build(int l, int r, int rt)
{
neg[rt] = Min[rt] = INF, Max[rt] = -INF;
if(l==r) return ;
int m = (l+r)>>1;
build(lson);
build(rson);
} inline void Down(int rt)
{
if(neg[rt]==-INF)
{
int ls=rt<<1, rs=ls|1;
fxor(neg[ls]), fxor(neg[rs]);
Min[ls] = -Min[ls];
Max[ls] = -Max[ls];
swap(Max[ls], Min[ls]);
Min[rs] = -Min[rs];
Max[rs] = -Max[rs];
swap(Max[rs], Min[rs]);
neg[rt] = INF;
}
} inline void update(int L, int R, int c, int l, int r, int rt)
{
if(L<=l && R>=r){
if(c>-INF) Min[rt] = Max[rt] = c;
else{
fxor(neg[rt]);
Min[rt] = -Min[rt];
Max[rt] = -Max[rt];
swap(Min[rt], Max[rt]);
}
return ;
}
Down(rt);
int m = (l+r)>>1;
if(L<=m) update(L, R, c, lson);
if(R>m) update(L, R, c, rson);
Up(rt);
} inline int query(int L, int R, int l, int r, int rt)
{
if(L<=l && r<=R) return Max[rt];
Down(rt);
int m = (l+r)>>1;
int ans = -INF;
if(L<=m) ans = max(ans, query(L, R, lson));
if(R>m) ans = max(ans, query(L, R, rson));
return ans;
} inline int lcaQ(int u, int v, bool flag)
{
int fu=top[u], fv=top[v];
int ans = -INF;
while(fv!=fu)
{
if(dep[fu]<dep[fv])
{
swap(fv, fu); swap(u, v);
}
if(flag) ans = max(ans,query(id[fu], id[u], 1, gid, 1));
else update(id[fu], id[u], -INF, 1, gid, 1);
u = fa[fu];
fu = top[u];
}
if(dep[u]<dep[v]) swap(u,v);
if(u!=v)
{
if(flag) ans = max(ans, query(id[v]+1, id[u], 1, gid, 1));
else update(id[v]+1, id[u], -INF, 1, gid, 1);
}
return ans;
} inline void solve()
{
ecnt = 0, gid = 0;
memset(pre, -1, sizeof(pre));
scanf("%d", &n);
int u, v, w;
for(int i=1; i<n; i++)
{
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w);
}
sz[0] = 0;
dfs(1, 1, 0);
getpos(1, 1); build(1, gid , 1);
for(int i=1; i<ecnt; i+=2)
{
if(dep[e[i].u] < dep[e[i].v]) swap(e[i].u, e[i].v);
update(id[e[i].u], id[e[i].u], e[i].w, 1, gid, 1);
} char str[15];
while(scanf("%s", str)>0 && str[0]!='D')
{
scanf("%d%d", &u, &v);
if(str[0]=='Q')
printf("%d\n",lcaQ(u, v, 1));
else if(str[0]=='N')
lcaQ(u, v, 0);
else
update(id[e[2*u-1].u], id[e[2*u-1].u], v, 1, gid, 1);
}
} int main()
{
// freopen("in.txt", "r", stdin);
cin>>_;
while(_--) solve();
return 0;
}
poj 3237 Tree [LCA] (树链剖分)的更多相关文章
- poj 3237 Tree(树链剖分,线段树)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 7268 Accepted: 1969 Description ...
- POJ 3237 Tree (树链剖分)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 2825 Accepted: 769 Description ...
- POJ 3237 Tree 【树链剖分】+【线段树】
<题目链接> 题目大意: 给定一棵树,该树带有边权,现在对该树进行三种操作: 一:改变指定编号边的边权: 二:对树上指定路径的边权全部取反: 三:查询树上指定路径的最大边权值. 解题分析: ...
- HDU 3966 & POJ 3237 & HYSBZ 2243 树链剖分
树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...
- POJ 3237 Tree (树链拆分)
主题链接~~> 做题情绪:了. 解题思路: 主要注意如何区间更新就ok了 . 树链剖分就是树上的线段树. 代码: #include<iostream> #include<sst ...
- POJ 3723 Tree(树链剖分)
POJ 3237 Tree 题目链接 就多一个取负操作,所以线段树结点就把最大和最小值存下来,每次取负的时候,最大和最小值取负后.交换就可以 代码: #include <cstdio> # ...
- hdu Dylans loves tree [LCA] (树链剖分)
Dylans loves tree view code#pragma comment(linker, "/STACK:1024000000,1024000000") #includ ...
- HDU 3237 Tree(树链剖分)(线段树区间取反,最大值)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 9123 Accepted: 2411 Description ...
- POJ 3237:Tree(树链剖分)
http://poj.org/problem?id=3237 题意:树链剖分.操作有三种:改变一条边的边权,将 a 到 b 的每条边的边权都翻转(即 w[i] = -w[i]),询问 a 到 b 的最 ...
随机推荐
- C#写文本日志帮助类(支持多线程)
代码: using System; using System.Configuration; using System.IO; using System.Threading.Tasks; namespa ...
- AEAI WM V1.0 工作管理系统开源发版
AEAI WM工作管理系统是沈阳数通畅联软件公司基于AEAI DP平台开发的开源Java Web系统,用来管理记录日常工作内容及周工作内容等事务,AEAI WM工作管理系统包括一些核心的工作管理业务功 ...
- 使用BOM 的window对象属性打开新窗口
★ 示例1 要求:弹出新窗口,并向新窗口写入动态HTML代码 代码 <buttononclick="btnOpen()">打开新窗口</button> & ...
- oracle中文显示为问号
在用PL/sql查询时,中文显示为问号.经查证,发现问题为oracle字符集不支持中文导致的.修改oracle字符集,改为支持中文即可. 方法: 第一步:修改注册表. 开始-运行-输入regedit- ...
- 泛函编程(11)-延后计算-lazy evaluation
延后计算(lazy evaluation)是指将一个表达式的值计算向后拖延直到这个表达式真正被使用的时候.在讨论lazy-evaluation之前,先对泛函编程中比较特别的一个语言属性”计算时机“(s ...
- [moka同学笔记]百度编辑器Ueditor自动换行,添加<p>的问题(摘录)
原文:http://www.cnblogs.com/kissdodog/p/5419919.html 百度编辑器Ueditor其实蛮好用的,后来使用了一段时间发现,每次打开后又保存,发现都会往内容的 ...
- 【背景建模】VIBE
ViBe是一种像素级的背景建模.前景检测算法,该算法主要不同之处是背景模型的更新策略,随机选择需要替换的像素的样本,随机选择邻域像素进行更新.在无法确定像素变化的模型时,随机的更新策略,在一定程度上可 ...
- 将 C# 编译为原生机器码
C# 用户似乎都希望 C# 可以和 C++ 一样编译为本地的机器码.如果 C# 可以编译为机器码,将可以做到: 1. 效率提高,可以取代 C++ . 2. 反编译. 当然微软在商业利益的考虑下 ...
- VS2010中重命名项目
通常,在项目开发初始,一般都是先做一个Demo,以方便进行修改设计.演示等,这可能导致项目命名并不符合最后的规范,则需要修改项目名称.VS没有推出这方面针对性的功能,网友们也纷纷自己写了软件. 方案一 ...
- 获取经过跳转后的url地址
粗略一算,不写code已经好几个月了. 昨日受兄弟所托,为他写了一个小小的程序. 程序功能: 自动获取跳转后的Url地址 如下图所示: (newUrl.txt为转换后的地址信息...) 实现过程: 每 ...