Interval modification of the kd-tree, marking, the next pass.
Each time you ask, you can find the root from the point of inquiry, then pass it down, then answer the question.
#include <cstdio> #include <algorithm> #include <cstring>using namespace std; #define N 100001#define KD 2int n,root,m,q,qp[2][kd],fa[n],val,delta[n];bool dn;struct node{int ch[2],w,minn[kd],maxx[kd],p[kd],id; void Init () {for (int i=0;i<kd;++i) minn[i]=maxx[i]=p[i]; }}t[n];bool operator < (const node &a,const node &b) {return A.P[DN] < B.P[DN];} inline void pushup (const int &rt) {for (Int. i=0;i<2;++i) if (T[rt].ch[i]) for (int j=0;j<kd;++j) {t[rt].minn[j]=min (t[rt].minn[j],t[t[rt].ch[i]].minn[j]); T[rt].maxx[j]=max (T[rt].maxx[j],t[t[rt].ch[i]].maxx[j]); }}inline void pushdown (const int &rt) {if (Delta[rt]) {T[RT].W=DELTA[RT]; for (int i=0;i<2;++i) DELTA[T[RT].CH[I]]=DELTA[RT]; delta[rt]=0; }}int buildtree (int l=1,int r=n,bool d=0) {dn=d; int m= (l+r>>1); Nth_element (t+l,t+m,t+r+1); T[M]. Init (); IF (l!=m) T[m].ch[0]=buildtree (l,m-1,d^1); if (m!=r) T[m].ch[1]=buildtree (m+1,r,d^1); Pushup (m); return m;} void Update (int rt=root) {if (qp[0][0] <= t[rt].minn[0] && t[rt].maxx[0] <= qp[0][1] && qp[1][0 ] <= t[rt].minn[1] && t[rt].maxx[1] <= qp[1][1]) {delta[rt]=val; Return } pushdown (RT); if (Qp[0][0] <= t[rt].p[0] && t[rt].p[0] <= qp[0][1] && qp[1][0] <= t[rt].p[1] && T[rt] . p[1] <= qp[1][1]) t[rt].w=val; for (int i=0;i<2;++i) if (T[rt].ch[i] && qp[0][0] <= t[t[rt].ch[i]].maxx[0] && T[t[rt].ch[i] ].minn[0] <= qp[0][1] && qp[1][0] <= t[t[rt].ch[i]].maxx[1] && t[t[rt].ch[i]].minn[1] <= qp[ 1][1]) Update (T[rt].ch[i]);} void query (int U) {if (Fa[u]) Query (Fa[u]); Pushdown (U);} int Zu;int v[n],next[n],first[n],e;void addedge (const int &u,const int &v) {v[++e]=v; Next[e]=first[u]; First[u]=e;} int dep[n],dfn[n],dfr[n];void dfs (int U) {dfn[u]=++e; T[u].w=1; T[u].p[0]=e; T[u].p[1]=dep[u]; T[u].id=u; for (int i=first[u];i;i=next[i]) {dep[v[i]]=dep[u]+1; DFS (V[i]); } dfr[u]=e;} typedef long long ll; #define MOD 1000000007llll ans;int ma[n];int Main () {//Freopen ("Bzoj4154.in", "R", stdin); scanf ("%d", &zu); for (; zu;--zu) {int x,dis; scanf ("%d%d%d", &n,&m,&q); for (int i=2;i<=n;++i) {scanf ("%d", &x); Addedge (X,i); } e=0; Dep[1]=1; DFS (1); Buildtree (); Root= (1+n>>1); for (int i=1;i<=n;++i) {ma[t[i].id]=i; for (int j=0;j<2;++j) if (t[i].ch[j]) fa[t[i].ch[j]]=i; } for (int i=1;i<=q;++i) {scanf ("%d%d%d", &x,&dis,&val); if (!val) {Query (ma[x]); Ans= (ans+ (LL) i* (LL) t[ma[x]].w%mod)%mod; } else {qp[0][0]=dfn[x]; QP[0][1]=DFR[X]; QP[1][0]=DEP[X]; Qp[1][1]=dep[x]+dis; Update (); }} printf ("%lld\n", ans); for (int i=1;i<=n;++i) t[i].ch[0]=t[i].ch[1]=0; memset (delta+1,0,sizeof (int) *n); memset (fa+1,0,sizeof (int) *n); ans=e=0; memset (first+1,0,sizeof (int) *n); } return 0;}
"Kd-tree" bzoj4154 [ipsc2015]generating Synergy