每个点变成二维平面上一个点,横坐标dfn纵坐标dep,这样就变成了矩形染色单点查询。
正解是kdt?然而不会啊,好在内存卡的不是很紧,二维线段树动态开点就可以过了
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<iomanip> #include<cmath> #include<cstring> #include<ctime> #include<vector> #include<stack> #include<queue> #include<set> #include<bitset> #include<map> using namespace std; #define MAXN 100010 #define MAXM 27600010 #define INF 1000000000 #define MOD 1000000007 #define ll long long #define eps 1e-8 struct vec{ int to; int fro; }; char ch,B[1<<10],*S=B,*TT=B; #define getc() (S==TT&&(TT=(S=B)+fread(B,1,1<<10,stdin),S==TT)?0:*S++) inline int read() { int x=0,f=1;char ch=getc(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();} return x*f; } vec mp[MAXN]; int tai[MAXN],cnt; int n,m,c; int tot; int son[MAXM][2],col[MAXM],vis[MAXM]; int rt[MAXN*4]; int dep[MAXN],dfn[MAXN],fa[MAXN],tim; int siz[MAXN]; int T; inline void be(int x,int y){ mp[++cnt].to=y; mp[cnt].fro=tai[x]; tai[x]=cnt; } void ins2(int &x,int y,int z,int p){ if(!x){ x=++tot; son[x][0]=son[x][1]=0; vis[x]=0; col[x]=0; } if(y==z){ col[x]=1; vis[x]=T; return ; } int mid=y+z>>1; if(p<=mid){ ins2(son[x][0],y,mid,p); }else{ ins2(son[x][1],mid+1,z,p); } } void ins1(int x,int y,int z,int p1,int p2){ ins2(rt[x],1,n,p2); if(y==z){ return ; } int mid=y+z>>1; if(p1<=mid){ ins1(x<<1,y,mid,p1,p2); }else{ ins1(x<<1|1,mid+1,z,p1,p2); } } void dfs(int x){ int i,y; dep[x]=dep[fa[x]]+1; dfn[x]=++tim; siz[x]=1; ins1(1,1,n,dfn[x],dep[x]); for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; dfs(y); siz[x]+=siz[y]; } } void change2(int x,int y,int z,int l,int r,int cv){ if(!x){ return ; } if(y==l&&z==r){ col[x]=cv; vis[x]=T; return ; } int mid=y+z>>1; if(r<=mid){ change2(son[x][0],y,mid,l,r,cv); }else if(l>mid){ change2(son[x][1],mid+1,z,l,r,cv); }else{ change2(son[x][0],y,mid,l,mid,cv); change2(son[x][1],mid+1,z,mid+1,r,cv); } } void change1(int x,int y,int z,int l,int r,int l2,int r2,int cv){ if(y==l&&z==r){ change2(rt[x],1,n,l2,r2,cv); return ; } int mid=y+z>>1; if(r<=mid){ change1(x<<1,y,mid,l,r,l2,r2,cv); }else if(l>mid){ change1(x<<1|1,mid+1,z,l,r,l2,r2,cv); }else{ change1(x<<1,y,mid,l,mid,l2,r2,cv); change1(x<<1|1,mid+1,z,mid+1,r,l2,r2,cv); } } int anst,ansc; void ask2(int x,int y,int z,int p){ if(!x){ return ; } if(vis[x]>anst){ ansc=col[x]; anst=vis[x]; } if(y==z){ return ; } int mid=y+z>>1; if(p<=mid){ ask2(son[x][0],y,mid,p); }else{ ask2(son[x][1],mid+1,z,p); } } void ask1(int x,int y,int z,int p1,int p2){ ask2(rt[x],1,n,p2); if(y==z){ return ; } int mid=y+z>>1; if(p1<=mid){ ask1(x<<1,y,mid,p1,p2); }else{ ask1(x<<1|1,mid+1,z,p1,p2); } } int main(){ int i,x,y,z,o; int tmp; // freopen("g1.in","r",stdin); tmp=read(); while(tmp--){ cnt=0; tot=0; ll ans=0; tim=0; memset(rt,0,sizeof(rt)); memset(tai,0,sizeof(tai)); n=read(); c=read(); m=read(); for(i=2;i<=n;i++){ x=read(); fa[i]=x; be(x,i); } T=1; dfs(1); for(i=1;i<=m;i++){ x=read(); y=read(); o=read(); if(!o){ anst=0; ask1(1,1,n,dfn[x],dep[x]); ans+=(ll)((ll)i*ansc)%MOD; ans%=MOD; //cout<<ansc<<endl; }else{ T++; change1(1,1,n,dfn[x],dfn[x]+siz[x]-1,dep[x],dep[x]+y,o); } } printf("%lld\n",ans); } return 0; } /* 1 4 3 7 1 2 2 3 0 0 2 1 3 3 0 0 1 0 2 2 0 0 4 1 1 4 0 0 */