https://www.luogu.com.cn/problem/P7710
相当于是这题丢到树上的版本
luogu P5309 [Ynoi2011] 初始化
不太会去掉log,
考虑一个修改i对一个询问j有几个限制,首先是时间 t i < t j t_i<t_j ti<tj这一维,
第二维是要满足 l i < l j < = r i l_i<l_j<=r_i li<lj<=ri
第三维是 d e p [ u j ] = d e p [ u i ] + y ( m o d x ) dep[u_j]=dep[u_i]+y(\mod x) dep[uj]=dep[ui]+y(modx)
第三维按照上面那个套路搞个阈值分治即可
加几个卡常技巧即可
code:
#include<bits/stdc++.h>
#define N 600050
using namespace std;
inline int read() {register int x = 0;register char ch = getchar();for(; ch < '0' || ch > '9'; ) ch = getchar();for(; ch >= '0' && ch <= '9'; ) x = (x << 3) + (x << 1) + (ch - 48), ch = getchar();return x;
}
inline void PRT(register int x) {int s[20], top = 0;while(x) s[++ top] = x % 10, x /= 10;if(!top) s[++ top] = 0;while(top) putchar(s[top --] + '0');puts("");
}
struct edge {int v, nxt;
} e[N << 1];
int p[N], eid;
void init() {memset(p, -1, sizeof p);eid = 0;
}
inline void insert(int u, int v) {e[eid].v = v;e[eid].nxt = p[u];p[u] = eid ++;
}
int n, m, dfn, tot, gs, L[N], R[N], dep[N], s1[606][606], s2[N], blo, ans[N << 2];
int ss1[606][606], ss2[N], py[N], ss0[N];
void dfs(int u) {L[u] = ++ dfn;py[dfn] = u;for(int i = p[u]; i + 1; i = e[i].nxt) {int v = e[i].v;dep[v] = dep[u] + 1;dfs(v);}R[u] = dfn;
}
inline void update(int x, register int y, int o) {if(x <= blo) s1[x][y] += o;else for(; y <= n; y += x) s2[y] += o;
}
inline int query(int x) {int ret = s2[x];for(register int i = 1; i <= blo; i ++) ret += s1[i][x % i];return ret;
}
inline void clear(int x, register int y) {if(x <= blo) s1[x][y] = 0;else for(; y <= n; y += x) s2[y] = 0;
}
struct Q {int l, x, y, o, id;
} q[N << 2], ls[N << 2];
void cdq(int l, int r) {if(l == r) return ;int mid = (l + r) >> 1;cdq(l, mid), cdq(mid + 1, r);int i = l, j = mid + 1, k = l - 1;while(i <= mid && j <= r) {if(q[i].l <= q[j].l) {if(!q[i].id) update(q[i].x, q[i].y, q[i].o);ls[++ k] = q[i ++];} else {if(q[j].id) ans[q[j].id] += query(q[j].x);ls[++ k] = q[j ++];}}while(j <= r) {if(q[j].id) ans[q[j].id] += query(q[j].x);ls[++ k] = q[j ++];}for(int w = l; w < i; w ++) if(!q[w].id) clear(q[w].x, q[w].y);while(i <= mid) {ls[++ k] = q[i ++];}for(int i = l; i <= r; i ++) q[i] = ls[i];
}
int main() {init();n = read(), m = read();for(int i = 2; i <= n; i ++) {int x;x = read();insert(x, i);}blo = sqrt(n);dfs(1);//for(int i = 1; i <= n; i ++) printf("%d ", dep[i]); printf("\n");for(int i = 1; i <= m; i ++) {int o, u, x, y, op;op = read(), u = read();if(op == 2) {q[++ tot] = (Q){L[u], dep[u], 0, 0, ++ gs};ans[gs] += ss0[u] + ss2[dep[u]];for(int j = 1; j <= blo; j ++)ans[gs] += ss1[j][dep[u] % j];//, printf("*%d*", ss1[j][dep[u] % j]);}else {x = read(), y = read(), o = read();y = (y + dep[u]) % x;q[++ tot] = (Q){L[u], x, y, o, 0};if(L[u] <= blo) {tot --;if(x <= blo) ss1[x][y] += o;else for(int j = y; j <= n; j += x) ss2[j] += o;for(int j = 1; j < L[u]; j ++) {int v = py[j];if(dep[v] % x == y) ss0[v] -= o;}}q[++ tot] = (Q){R[u] + 1, x, y, -o, 0};if(R[u] + blo >= n) {tot --;for(int j = R[u] + 1; j <= n; j ++) {int v = py[j];if(dep[v] % x == y) ss0[v] -= o;}}}}cdq(1, tot);for(int i = 1; i <= gs; i ++) PRT(ans[i]);return 0;
}