【kd-tree】bzoj4154 [Ipsc2015]Generating Synergy
区间修改的kd-tree,打标记,下传。
每次询问的时候,从询问点向上找到根,然后依次下传下来,再回答询问。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 100001 #define KD 2 int 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 1000000007ll ll 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; }
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/