bzoj 3626 LCA
这一道题咋一看只觉得是离线,可以求出所有的f(1,i,z), 答案就等于f(1,r,z)-f(1,l-1,z)。但是没有具体的做法,但是求LCA的深度和有一个非常巧妙的做法,每加一个点,就把这个点到根的路径上的点权值+1,这样计算某个点和之前所有点LCA深度和就可以统计这个点到根的路径上的点的权值和。这样就可以用树链剖分很快的修改和得出答案,这题就解决了。
上代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#define N 51000
#define yu 201314
using namespace std; struct sss
{
int place, askp;
int num, nump;
}ask[N*];
struct ss
{
int num, push;
}t[N*];
int n, m, nowplace = ;
int p[N], v[N], next[N], bnum = ;
int ans[N][] = {};
int fa[N], deep[N], siz[N], son[N], w[N], top[N]; bool cmp(sss x, sss y) { return x.place < y.place; } void addbian(int x, int y)
{
bnum++; next[bnum] = p[x]; p[x] = bnum; v[bnum] = y;
} void build_tree(int now, int l, int r)
{
t[now].num = ; t[now].push = ;
if (l == r) return; int mid = (l+r)/;
build_tree(now*, l, mid); build_tree(now*+, mid+, r);
} void dfs_1(int now, int fat, int de)
{
int k = p[now]; fa[now] = fat; deep[now] = de;
int maxsonnum = ; siz[now] = ; son[now] = ;
while (k)
{
if (v[k] != fat)
{
dfs_1(v[k], now, de+);
siz[now] += siz[v[k]];
if (siz[v[k]] > maxsonnum)
{
maxsonnum = siz[v[k]];
son[now] = v[k];
}
}
k = next[k];
}
return;
} void dfs_2(int now, int fat, int nowtop)
{
int k = p[now]; top[now] = nowtop; w[now] = ++nowplace;
if (son[now]) dfs_2(son[now], now, nowtop);
while (k)
{
if (v[k] != son[now] && v[k] != fat)
dfs_2(v[k], now, v[k]);
k = next[k];
}
return;
} void downdate(int now, int l, int r)
{
if (!t[now].push) return; int mid = (l+r)/;
t[now*].push += t[now].push;
t[now*+].push += t[now].push;
t[now*].num += (mid-l+) * t[now].push;
t[now*+].num += (r-mid) * t[now].push;
if (t[now*].num > yu) t[now*].num %= yu;
if (t[now*+].num > yu) t[now*+].num %= yu;
t[now].push = ; return;
} void tadd(int now, int l, int r, int al, int ar)
{
if (al <= l && r <= ar)
{
t[now].num += r-l+;
if (t[now].num > yu) t[now].num %= yu;
t[now].push ++; return;
}
int mid = (l+r)/; downdate(now, l, r);
if (al <= mid) tadd(now*, l, mid, al, ar);
if (ar > mid) tadd(now*+, mid+, r, al, ar);
t[now].num = t[now*].num + t[now*+].num;
if (t[now].num > yu) t[now].num %= yu;
} int task(int now, int l, int r, int al, int ar)
{
if (al <= l && r <= ar) return t[now].num;
int mid = (l+r)/, zans = ; downdate(now, l, r);
if (al <= mid) zans = task(now*, l, mid, al, ar);
if (ar > mid) zans += task(now*+, mid+, r, al, ar);
if (zans > yu) zans %= yu;
return zans;
} int askk(int u, int v)
{
int f1 = top[u], f2 = top[v];
if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); }
if (f1 == f2)
{
if (u == v) return task(, , n, w[u], w[u]);
return task(, , n, min(w[u], w[v]), max(w[u], w[v]));
}
int zans = task(, , n, w[f1], w[u]);
zans += askk(fa[f1], v); if (zans > yu) zans %= yu;
return zans;
} void add(int u, int v)
{
int f1 = top[u], f2 = top[v];
if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); }
if (f1 == f2)
{
if (u == v) tadd(, , n, w[u], w[u]);
else tadd(, , n, min(w[u], w[v]), max(w[u], w[v]));
return;
}
tadd(, , n, w[f1], w[u]); add(fa[f1], v);
} int main()
{
scanf("%d%d", &n, &m); build_tree(, , n);
for (int i = ; i < n; ++i)
{
int x; scanf("%d", &x);
addbian(x+, i+);
}
dfs_1(, , ); dfs_2(, , );
for (int i = ; i <= m; ++i)
{
int x, y, z; scanf("%d%d%d", &x, &y, &z); x++; y++; z++;
ask[i*-].place = x-; ask[i*-].askp = z;
ask[i*-].num = i; ask[i*-].nump = ;
ask[i*].place = y; ask[i*].askp = z;
ask[i*].num = i; ask[i*].nump = ;
}
sort(ask+, ask++*m, cmp); int nowplace = ;
for (int i = ; i <= m*; ++i)
{
while (ask[i].place > nowplace)
{
nowplace++;
add(, nowplace);
}
if (ask[i].place)
ans[ask[i].num][ask[i].nump] = askk(, ask[i].askp);
else ans[ask[i].num][ask[i].nump] = ;
}
for (int i = ; i <= m; ++i)
printf("%d\n", (ans[i][]+yu-ans[i][]) % yu);
return ;
}
bzoj 3626 LCA的更多相关文章
- BZOJ 3626 LCA(离线+树链剖分)
首先注意到这样一个事实. 树上两个点(u,v)的LCA的深度,可以转化为先将u到根路径点权都加1,然后求v到根路径上的总点权值. 并且该题支持离线.那么我们可以把一个区间询问拆成两个前缀和形式的询问. ...
- BZOJ 3626 LCA(离线+树链剖分+差分)
显然,暴力求解的复杂度是无法承受的. 考虑这样的一种暴力,我们把 z 到根上的点全部打标记,对于 l 到 r 之间的点,向上搜索到第一个有标记的点求出它的深度统计答案.观察到,深度其实就是上面有几个已 ...
- [BZOJ 3626] [LNOI2014] LCA 【树链剖分 + 离线 + 差分询问】
题目链接: BZOJ - 3626 题目分析 考虑这样的等价问题,如果我们把一个点 x 到 Root 的路径上每个点的权值赋为 1 ,其余点的权值为 0,那么从 LCA(x, y) 的 Depth 就 ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1272 Solved: 451[Submit][Status ...
- bzoj 3626: [LNOI2014]LCA 离线+树链剖分
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 426 Solved: 124[Submit][Status] ...
- BZOJ 3626: [LNOI2014]LCA( 树链剖分 + 离线 )
说多了都是泪啊...调了这么久.. 离线可以搞 , 树链剖分就OK了... -------------------------------------------------------------- ...
- BZOJ 3626 [LNOI2014]LCA:树剖 + 差分 + 离线【将深度转化成点权之和】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3626 题意: 给出一个n个节点的有根树(编号为0到n-1,根节点为0,n <= 50 ...
- BZOJ 3626 [LNOI2014]LCA 树剖+(离线+线段树 // 在线+主席树)
BZOJ 4012 [HNOI2015]开店 的弱化版,离线了,而且没有边权(长度). 两种做法 1 树剖+离线+线段树 这道题求的是一个点zzz与[l,r][l,r][l,r]内所有点的lcalca ...
随机推荐
- 异常捕捉 ( try catch finally ) 你真的掌握了吗?
前言:java 中的异常处理机制你真的理解了吗?掌握了吗?catch 体里遇到 return 是怎么处理? finally 体遇到 return 怎么办?finally 体里有 System.exit ...
- 关于Android与pc通信时中文乱码的分析和解决
初步实现了Android与pc服务器的通信之后,又碰到了传说中令人头疼不已的中文乱码问题.既然出现了乱码,那么原因自然是协议不通了.我们知道eclipse中默认的编码标准是GBK,而安卓程序开发所默认 ...
- 框架使用的技术主要是SpringMVC 在此基础上进行扩展
框架使用的技术主要是SpringMVC 在此基础上进行扩展 1 Web前端使用 2 前段控制器采用SpringMVC零配置 3 IOC容器Spring 4 ORM使用 Mybites或者hiberna ...
- [Javascript] Either Functor
Either Functor: // API Right(val) // resolve the value Left(val) // return error message Examples: m ...
- 苹果Swift语言中文教程资源汇总
苹果swift语言中文教程(零)搭配环境以及代码执行成功http://vjiazhi.com/kaifa/1014.html 苹果Swift语言中文教程(一)基础数据类型 http://vjiazhi ...
- 【v2.x OGE教程 19】 引擎状态控制
1.手机button监听 OGE中提供了在BaseGameLauncher(GameLauncher的父类)和IScene(Scene实现的接口)中定义了onKeyUp和onKeyDown的方法.使得 ...
- C++之运算符重载(1)
在前一节中曾提到过,C++中运行时的多态性主要是通过虚函数来实现的,而编译时的多态性是由函数重载和运算符重载来实现的.这一系列我将主要讲解C++中有关运算符重载方面的内容.在每一个系列讲解之前,都会有 ...
- 如何删除google流氓扩展(强制安装,并且无权限删除)
chrome现在也是流氓遍地跑, 没比IE安全到哪里. TubeAdblocKer 这个流氓扩展,强制安装,无法删除.google了一大堆方法,全部无效.祭出了filelocator这个神器之后,终于 ...
- SSIS 学习(0):企业离 BI 还有多远?【转】
上一篇文章<<企业需要BI吗?>>发表后,有一些网友反应:BI现在还不火:BI仅仅在一些大企业有用武之地,中小型企业只能是望其项背,遥不可及了:BI仅仅是一些花拳秀腿而已,如果 ...
- struts2拦截器源码分析
前面博客我们介绍了开发struts2应用程序的基本流程(开发一个struts2的实例),通过前面我们知道了struts2实现请求转发和配置文件加载都是拦截器进行的操作,这也就是为什么我们要在web.x ...