[luogu P4211] [LNOI2014]LCA
題解
首先考慮把詢問拆成兩個字首和
然後對於把把每個點一次插入,每次把那個點到根的所有點權值+1
詢問就是z到根的路徑權值和
樹剖一下就做完了
#include<bits/stdc++.h>
#define mod 201314
#define ll long long
using namespace std;
const int N = 530005;
const int INF = 9999999;
struct A{
int v, next;
}e[N];
int eid, p[N], w[N], fa[N], top[N], size[N], id[N], deep[N], sz;
int a[N], n, sum[N], fid[N], col[N];
void update(int u){
sum[u] = sum[u<<1] + sum[u<<1|1];
}
void pushdown(int rt, int l, int r){
int mid = (l + r) >> 1;
sum[rt<<1] += (mid - l + 1) * col[rt];
sum[rt<<1|1] += (r - mid) * col[rt];
col[rt<<1] += col[rt];
col[rt<<1|1] += col[rt];
col[rt] = 0;
}
void Add(int l, int r, int L, int R, int rt, int o){ //printf("%d %d %d %d %d %d\n", l, r, rt, o, L, R);
pushdown(rt, l, r);
if(L <= l && r <= R){
sum[rt] += (r - l + 1) * o;
col[rt] += o;
return;
}
int mid = (l + r) >> 1,ret = 0;
if(L <= mid) Add(l, mid, L, R, rt<<1, o);
if(R > mid) Add(mid + 1, r, L, R, rt<<1|1, o);
update(rt);
}
int querys(int l, int r, int L, int R, int rt){
pushdown(rt, l, r);
if(L <= l && r <= R){
return sum[rt];
}
int mid = (l + r) >> 1,ret = 0;
if(L <= mid) ret += querys(l, mid, L, R, rt<<1);
if(R > mid) ret += querys(mid + 1, r, L, R, rt<<1|1);
return ret;
}
void init(){
memset(p, -1, sizeof(p));
eid = 0;
}
void add(int u, int v){
e[eid].next = p[u];
e[eid].v = v;
p[u] = eid ++;
}
void dfs1(int u){
size[u] = 1;
for(int i = p[u]; i + 1; i = e[i].next){
int v = e[i].v;
if(fa[u] == v) continue;
deep[v] = deep[u] + 1;
fa[v] = u;
dfs1(v);
size[u] += size[v];
if(size[v] > size[w[u]]) w[u] = v;
}
}
void dfs2(int u){
id[u] = ++ sz;
if(w[u]) top[w[u]]=top[u], dfs2(w[u]);
for(int i = p[u]; i + 1; i = e[i].next){
int v = e[i].v;
if(fa[u] == v || v == w[u]) continue;
top[v] = v;
dfs2(v);
}
}
int query(int u, int v){if(!u) return 0;
int ret = 0;
while(top[u] != top[v]){
if(deep[top[u]] <= deep[top[v]]) swap(u, v);
ret += querys(1, n, id[top[u]], id[u], 1);
ret %= mod;
u = fa[top[u]];
}
if(deep[u] < deep[v]) swap(u, v);
ret += querys(1, n, id[v], id[u], 1);
return ret;
}
void change(int u, int v, int o){// printf("%d*%d\n", u, v);
if(!u) return;
int ret = 0;
while(top[u] != top[v]){
if(deep[top[u]] <= deep[top[v]]) swap(u, v);
Add(1, n, id[top[u]], id[u], 1, o);
u = fa[top[u]];
}
if(deep[u] < deep[v]) swap(u, v);
Add(1, n, id[v], id[u], 1, o);
}
struct QQ{
int l, z, id;
}q[N];
int cmp(QQ a, QQ b){
return a.l < b.l;
}
int ans[N], F[N], m, tot;
int main(){
init();
scanf("%d%d", &n, &m);
for(int i = 2; i <= n; i++){
int v;
scanf("%d", &v);
v ++;
add(v, i);
}
dfs1(1);dfs2(1);
// printf(" size:");for(int i = 1 ; i <= n; i ++) printf("%d ", size[i]); printf("\n");
// printf("father:");for(int i = 1 ; i <= n; i ++) printf("%d ", fa[i]); printf("\n");
// printf(" top:");for(int i = 1 ; i <= n; i ++) printf("%d ", top[i]); printf("\n");
// printf(" deep:");for(int i = 1 ; i <= n; i ++) printf("%d ", deep[i]); printf("\n");
// printf("weight:");for(int i = 1 ; i <= n; i ++) printf("%d ", w[i]); printf("\n");
for(int i = 1; i <= m; i ++){
int u, v, z;
scanf("%d%d%d", &u, &v, &z);
u ++, v ++, z ++;
q[++ tot].l = u - 1, q[tot].z = z, q[tot].id = i;
q[++ tot].l = v, q[tot].z = z, q[tot].id = i;
}
sort(q + 1, q + 1 + tot, cmp);
int j = 1;
for(int i = 0; i <= n; i ++){
change(1, i, 1);//printf("\n");
for(;q[j].l == i;){
if(!F[q[j].id]) ans[q[j].id] -= query(1, q[j].z), F[q[j].id] = 1;
else ans[q[j].id] += query(1, q[j].z);
j ++;
}
}
for(int i = 1; i <= m; i ++) printf("%d\n", (ans[i] + mod) % mod);
return 0;
}
相關文章
- bzoj3626: [LNOI2014]LCA(離線處理+樹鏈剖分)
- lca
- 求 LCA
- RMQ求lcaMQ
- DFN 序求 LCA
- 求解 LCA の方法
- LCA(倍增與Tarjan)
- LCA + 樹上倍增
- LCA最近公共祖先
- 最近公共祖先 LCA
- Luogu P10812
- LCA學習筆記筆記
- 樹上公共祖先(LCA)
- HDU 2586 倍增 / Tarjan LCA
- luogu2516題解
- luogu_P3373 Solution
- 【Luogu1048】採藥
- 【luogu1816】忠誠
- 淺談倍增法求解LCA
- LCA的離線快速求法
- Day 5 LCA 最近公共祖先
- Lca相關演算法演算法
- [PEP] Luogu 二週年記
- 關於LCA的幾點想法
- POJ1330 Nearest Common Ancestors【LCA】REST
- Luogu8990 做題記錄
- luogu P6835 概率DP 期望
- $Luogu P2029$ 跳舞 題解
- bzoj5293: [Bjoi2018]求和(Lca)
- luogu-P3853 路標設定
- luogu P5867 【[SEERC2018]Fishermen】
- [luogu3709][大爺的字串題]字串
- 【Luogu1616】瘋狂的採藥
- 【luogu3373】模板 線段樹 2
- 【luogu3372】線段樹 1 模板
- 貨車運輸(LCA+最大生成樹)
- POJ 3694 Network 邊雙連通分量+LCA
- Luogu P5563 [Celeste-B] No More Running