bzoj4154: [Ipsc2015]Generating Synergy
//Achen #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<vector> #include<queue> #include<ctime> #include<cmath> const int N=1e5+7; const int mod=1e9+7; typedef long long LL; using namespace std; int rt,n,y,D,T,c,q,data[N][2][2],ch[N][2],col[N],lz[N]; LL ans; template<typename T> void read(T &x) { char ch=getchar(); x=0; T f=1; while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar(); if(ch=='-') f=-1,ch=getchar(); for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f; } struct node{ int d[2]; friend bool operator <(const node &A,const node&B) { return A.d[D]<B.d[D]; } }a[N],tp; int ecnt,fir[N],nxt[N],to[N],fa[N]; void add(int u,int v) { nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; } int dfs_clock,dfn[N],low[N],R[N]; void dfs(int x) { dfn[x]=low[x]=++dfs_clock; R[x]=R[fa[x]]+1; a[x].d[0]=dfn[x]; a[x].d[1]=R[x]; for(int i=fir[x];i;i=nxt[i]) { dfs(to[i]); low[x]=max(low[x],low[to[i]]); } } void update(int x) { for(int i=0;i<2;i++) for(int j=0;j<2;j++) data[x][i][j]=a[x].d[i]; for(int i=0;i<2;i++) if(y=ch[x][i]) for(int j=0;j<2;j++) data[x][j][0]=min(data[x][j][0],data[y][j][0]), data[x][j][1]=max(data[x][j][1],data[y][j][1]); } #define lc ch[x][0] #define rc ch[x][1] int build(int l,int r,int k) { if(l>r) return 0; D=k; int mid=((l+r)>>1); nth_element(a+l,a+mid,a+r+1); ch[mid][0]=build(l,mid-1,k^1); ch[mid][1]=build(mid+1,r,k^1); update(mid); return mid; } void down(int x) { if(!lz[x]) return; if(lc) col[lc]=col[x],lz[lc]=1; if(rc) col[rc]=col[x],lz[rc]=1; lz[x]=0; } int in(int x) { return data[x][0][0]<=tp.d[0]&&data[x][0][1]>=tp.d[0] &&data[x][1][0]<=tp.d[1]&&data[x][1][1]>=tp.d[1]; } int ok(int x,int l1,int r1,int l2,int r2) { int f=1; if(!((data[x][0][0]>=l1&&data[x][0][0]<=r1) ||(data[x][0][1]>=l1&&data[x][0][1]<=r1)|| (data[x][0][0]<=l1&&data[x][0][1]>=r1))) f=0; if(!((data[x][1][0]>=l2&&data[x][1][0]<=r2) ||(data[x][1][1]>=l2&&data[x][1][1]<=r2)|| (data[x][1][0]<=l2&&data[x][1][1]>=r2))) f=0; return f; } int find(int x) { if(a[x].d[0]==tp.d[0]&&a[x].d[1]==tp.d[1]) return col[x]; down(x); int res=0; if(in(lc)) res=find(lc); if(!res&&in(rc)) res=find(rc); return res; } void change(int x,int l1,int r1,int l2,int r2,int v) { if(data[x][0][0]>=l1&&data[x][0][1]<=r1&& data[x][1][0]>=l2&&data[x][1][1]<=r2) { col[x]=v,lz[x]=1; return; } down(x); if(a[x].d[0]>=l1&&a[x].d[0]<=r1&& a[x].d[1]>=l2&&a[x].d[1]<=r2) col[x]=v; if(ok(lc,l1,r1,l2,r2)) change(lc,l1,r1,l2,r2,v); if(ok(rc,l1,r1,l2,r2)) change(rc,l1,r1,l2,r2,v); } void work() { dfs(1); for(int i=1;i<=n;i++) col[i]=1,lz[i]=0; rt=build(1,n,0); for(int i=1;i<=q;i++) { int x,h,c; read(x); read(h); read(c); if(!c) { tp.d[0]=dfn[x]; tp.d[1]=R[x]; (ans+=(LL)i*(find(rt)))%=mod; } else change(rt,dfn[x],low[x],R[x],R[x]+h,c); } printf("%lld\n",ans); } void init() { read(T); while(T--) { read(n); read(c); read(q); for(int i=2;i<=n;i++) { read(fa[i]); add(fa[i],i); } work(); ans=0; ecnt=0; memset(fir,0,sizeof(fir)); memset(data,0,sizeof(data)); memset(ch,0,sizeof(ch)); } } int main() { init(); return 0; }