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 ...
随机推荐
- 【XS128】Link error L1822 symbol _FADD / _FSUB/ _FDIV/ _FMUL.....错误解决的方法
转载请注明出处 因为阅历有限,篇幅不周之处还望指出,谢谢 假设方法确实奏效,请一定回复点赞哦,给后来人也是一种帮助,谢谢! 这是飞思卡尔 XS128平台比較常见的LINK错误. 可是要解决起来也比較头 ...
- 分享一个jQuery动态网格布局插件:Masonry(转)
在线演示 Masonry是 一款非常强大的jQuery动态网格布局插件,可以帮助开发人员快速开发类似剪贴画的界面效果.和CSS中float的效果不太一样的地方在 于,float先水平排列,然后再垂直排 ...
- AS3 Signals
在项目中,使用as3内置事件框架必须通过自定义事件才可以实现值的传递,大量自定义事件.定义常量和整个事件派发的管理.添加侦听器.移除侦听器,或多或少都会带来大量的代码,而signals这个框架思想原来 ...
- show engine innodb status解读
xiaoboluo768 注:以下内容为根据<高性能mysql第三版>和<mysql技术内幕innodb存储引擎>的innodb status部分的个人理解,如果有错误,还 ...
- centos 配置NFS服务器
转载:http://boloveyo.blog.163.com/blog/static/203926187201232383956558/ 系统是CentOS5.6,假设NFS Server IP为1 ...
- Windows 之 获取管理员权限
新建文本文档,写入如下内容: Windows Registry Editor Version 5.00 [-HKEY_CLASSES_ROOT\*\shell\runas] [HKEY_CLASSES ...
- Sequence用堆排序
Description Given m sequences, each contains n non-negative integer. Now we may select one number fr ...
- Android进阶笔记11:ListView篇之ListView显示多种类型的条目(item)
ListView可以显示多种类型的条目布局,这里写显示两种布局的情况,其他类似. 1. 这是MainActivity,MainActivity的布局就是一个ListView,太简单了这里就不写了,直接 ...
- POJ 3069 Saruman's Army(贪心)
Saruman's Army Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Sub ...
- hdu 4374 单调队列优化动态规划
思路:我只想说,while(head<=rear&&que[rear].val+sum[j]-sum[que[rear].pos-1]<=dp[i-1][j]+num[i- ...