luogu P7710 [Ynoi2077] stdmxeypz
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;
}