P4211 [LNOI2014]LCA LCT
P4211 [LNOI2014]LCA
链接
思路
多次询问\(\sum\limits_{l \leq i \leq r}dep[LCA(i,z)]\)
可以转化成l到r上的点到根的路径+1
最后求一下1到z的路径和就是所求
区间\([l,r]\)是可以差分的
离线直接求就行了。
树剖常数小,但还是比LCT多个log
我的LCT好慢啊
代码
#include <bits/stdc++.h>
#define ls c[x][0]
#define rs c[x][1]
using namespace std;
const int N = 1e5 + 7, mod = 201314;
int read() {
int x = 0, f = 1; char s = getchar();
for (;s > '9' || s < '0'; s = getchar()) if (s == '-') f = -1;
for (;s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0';
return x * f;
}
int f[N], c[N][2], w[N], siz[N], sum[N], stak[N], lazy[N], lazytwo[N];
bool isroot(int x) {return c[f[x]][0] == x || c[f[x]][1] == x;}
void tag(int x){swap(ls,rs), lazy[x] ^= 1;}
void tagtwo(int x, int val) {
sum[x] = (sum[x] + 1LL * val * siz[x] % mod) % mod;
w[x] = (w[x] + val) % mod;
lazytwo[x] = (lazytwo[x] + val) % mod;
}
void pushdown(int x) {
if (lazy[x]) {
if (ls) tag(ls);
if (rs) tag(rs);
lazy[x] ^= 1;
}
if (lazytwo[x]) {
if (ls) tagtwo(ls, lazytwo[x]);
if (rs) tagtwo(rs, lazytwo[x]);
lazytwo[x] = 0;
}
}
void pushup(int x) {
sum[x] = (sum[ls] + sum[rs] + w[x]) % mod;
siz[x] = siz[ls] + siz[rs] + 1;
}
void rotate(int x) {
int y = f[x], z = f[y], k = c[y][1] == x, w = c[x][!k];
if (isroot(y)) c[z][c[z][1] == y] = x;
c[x][!k] = y;
c[y][k] = w;
if (w) f[w] = y;
f[x] = z;
f[y] = x;
pushup(y);
}
void splay(int x) {
int y = x, z = 0;
stak[++z] = y;
while (isroot(y)) stak[++z] = y = f[y];
while (z) pushdown(stak[z--]);
while (isroot(x)) {
y = f[x], z = f[y];
if (isroot(y)) rotate((c[y][0] == x)^(c[z][0] == y) ? x : y);
rotate(x);
}
pushup(x);
}
void access(int x) {
for (int y = 0; x;x = f[y = x])
splay(x), rs = y, pushup(x);
}
void makeroot(int x) {
access(x), splay(x);
tag(x);
}
int findroot(int x) {
access(x), splay(x);
while(ls) pushdown(x), x = ls;
return x;
}
void split(int x, int y) {
makeroot(x), access(y), splay(y);
}
void link(int x, int y) {
makeroot(x);
if (findroot(y) != x) f[x] = y;
}
void cut(int x, int y) {
makeroot(x);
if (findroot(y) == x && f[x] == y && !rs) {
f[x] = c[y][0] = 0;
pushup(y);
}
}
struct node {
int id, l, z, ans;
node(int a = 0, int b = 0, int c = 0) {
id = a, l = b, z = c;
}
} Q[N];
bool cmp1(const node &a, const node& b) {
return a.l < b.l;
}
bool cmp2(const node &a, const node& b) {
return a.id < b.id;
}
int main() {
// freopen("a.in", "r", stdin);
int n = read(), m = read();
for (int i = 2; i <= n; ++i) {
int x = read() + 1;
link(i, x);
}
for (int i = 1; i <= m; ++i) {
int l = read() + 1, r = read() + 1, z = read() + 1;
Q[i * 2 - 1] = node(i * 2 - 1, l - 1, z);
Q[i * 2] = node(i * 2, r, z);
}
m <<= 1;
sort(Q + 1, Q + 1 + m, cmp1);
int js = 1;
for (int i = 0; i <= n; ++i) {
if (i) split(1, i),tagtwo(i, 1);
while(Q[js].l == i) {
split(1, Q[js].z);
Q[js].ans = sum[Q[js].z];
js++;
}
}
sort(Q + 1, Q + 1 + m, cmp2);
for (int i = 2; i <= m; i += 2) {
int ans = Q[i].ans - Q[i - 1].ans;
ans = (ans % mod + mod) % mod;
printf("%d\n", ans);
}
return 0;
}
P4211 [LNOI2014]LCA LCT的更多相关文章
- P4211 [LNOI2014]LCA
P4211 [LNOI2014]LCA 链接 分析: 首先一种比较有趣的转化是,将所有点到1的路径上都+1,然后z到1的路径上的和,就是所有答案的deep的和. 对于多次询问,要么考虑有把询问离线,省 ...
- 洛谷 P4211 [LNOI2014]LCA 解题报告
[LNOI2014]LCA 题意 给一个\(n(\le 50000)\)节点的有根树,询问\(l,r,z\),求\(\sum_{l\le i\le r}dep[lca(i,z)]\) 一直想启发式合并 ...
- 洛谷 P4211 [LNOI2014]LCA (树链剖分+离线)
题目:https://www.luogu.org/problemnew/solution/P4211 相当难的一道题,其思想难以用言语表达透彻. 对于每个查询,区间[L,R]中的每个点与z的lca肯定 ...
- Luogu P4211 [LNOI2014]LCA
我去这道题的Luogu评级是假的吧,这都算黑题. 我们首先考虑把操作离线不强制在线的题目离线一下一般都要方便些 考虑差分,我们用\(f(x)\)表示\([1,x]\)之间的点与\(z\)的答案,那么显 ...
- 并不对劲的bzoj3626:loj2558:p4211:[LNOI2014]LCA
题目大意 有一棵有\(n\)(\(n\leq5*10^4\))个点的树,\(q\)(\(q\leq5*10^4\))次询问,每次给出\(l,r,x\)表示询问所有编号在\([l,r]\)的点与点\(x ...
- 洛谷$P4211\ [LNOI2014]\ LCA$ 树链剖分+线段树
正解:树剖+线段树 解题报告: 传送门$QwQ$ 看到$dep[lca]$啥的就想到之前托腮腮$CSP$模拟$D1T3$的那个套路,,, 然后试下这个想法,于是$dep[lca(x,y)]=\sum_ ...
- [火星补锅] 非确定性有穷状态决策自动机练习题Vol.3 T3 && luogu P4211 [LNOI2014]LCA 题解
前言: 这题感觉还是很有意思.离线思路很奇妙.可能和二次离线有那么一点点相似?当然我不会二次离线我就不云了. 解析: 题目十分清真. 求一段连续区间内的所有点和某个给出的点的Lca的深度和. 首先可以 ...
- 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 ...
随机推荐
- mybatis-plus 主键自增问题
主键不自增:返回值是插入的条数 <insert id="add" parameterType="EStudent"> insert into TSt ...
- latex中添加C++代码
用到listings宏包,模板如下: \documentclass[UTF8]{ctexart} \usepackage[a4paper,top=2cm,bottom=2cm,left=2cm,rig ...
- nginx部署angular
官方部署教程 本文将angular官网的示例项目 heroes(英雄指南) 部署到nginx. 使用angular cli编译项目 ng build 执行完成后会生成一个 dist 目录. 服务器配置 ...
- .NET CORE webapi epplus 导入导出 (实习第一个月的笔记)
最近有个需求就是网页表格里面的数据导出到excel 于是从各位前辈的博客园搜了搜demo 大部分非为两类 都是用的插件NPOI和Eppluse ,因此在这里就介绍Eppluse 用法,还有就是在博 ...
- [Windows] - DNS防污染工具Pcap_DNSProxy
最近试过非常多的DNS防污染工具(包括:dnsforwarder.dnsforwarder.dnscrypt-proxy.SimpleDNSCrypt等),感觉这个Pcap_DNSProxy简单.快捷 ...
- Fedora搭dokuwiki的步骤 以apache2.4为例
官网下载dokuwiki的包,解压到/var/www/html/下 修改dokuwiki的权限.拥有者/组 为apache 安装PHP 在/etc/httpd/conf 创建dokuwiki的配置文件 ...
- Mac安装Java的JDK并进行环境配置
一.下载JDK 1.直接进入oracle官网下载页: https://www.oracle.com/technetwork/java/javase/downloads/index.html 2.选择版 ...
- JavaScript 运算符(Operator)
一.算数运算符 1.加法(+) 表示操作数相加: 处理特殊值规则: 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来: 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后 ...
- BeanPostProcessor后置处理器原理以及ApplicationListener原理
BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的 1.BeanFactoryPostProcessor:BeanFactory的后置处理器; 在Bean ...
- MES被重新定义?做到这几点才算智能制造
在工业4.0背景下,推动智能制造,构建智能工厂.智能生产.智能物流和智能服务体系,我们需要对MES系统重新进行定义,主要从以下几个方面进行说明: MES深度融入企业运营环节 智能工厂中的机器将全部由软 ...