这一道题咋一看只觉得是离线,可以求出所有的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 ;
}

最新文章

  1. SQL优化技巧--远程连接对象引起的CTE性能问题
  2. [No000056]你无法真正占有一个人,包括你的爱人,先生或太太、小孩,以及你自己....
  3. BZOJ3468 : 滑雪
  4. search--搜索引擎的使用笔记
  5. std::map的clear()没有用?
  6. CPU厂商
  7. Could not load file or assembly &#39;MagickNet.dll&#39;
  8. js捕捉浏览器关闭事件-兼容几乎所有浏览器
  9. 给Notepad++ 加右键菜单带图标
  10. Jqury笔记
  11. vb编程代码大全
  12. react+flux编程实践(一) 基础篇
  13. python实现四则运算和效能分析
  14. Activiti(生成25张表)
  15. powerdessigner使用教程
  16. Java并发编程的艺术(三)——volatile
  17. 关于finecms v5 会员头像 任意文件上传漏洞分析
  18. 微信小程序-帝国cms会员系统调用
  19. static_cast、dynamic_cast、reinterpret_cast、和const_c
  20. PAT——1053. 住房空置率

热门文章

  1. sed常见使用方法总结
  2. [AngularJS] Lazy Loading modules with ui-router and ocLazyLoad
  3. 【读jQuery源码有感系列一】callee
  4. java 对象序列化
  5. 解析“extern”
  6. aspose.cells 模版
  7. 4K Block Size的Device和 Aligned IO
  8. TortoiseGit安装教程
  9. Skip list--reference wiki
  10. C# 之 未能映射路径