提交时间:2024-07-30 14:14:28
运行 ID: 30772
#include<bits/stdc++.h> using namespace std; #define int long long #define pii pair<int,int> #define fr first #define sc second #define mk make_pair #define inx(u) int I=h[(u)],v=edge[I].v;I;I=edge[I].nx,v=edge[I].v const int MAXN=200010,N=20,Mod=1000000007; int read(){int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x*f;} struct Edge{int v,nx;}edge[MAXN<<1];int h[MAXN],CNT;void add_side(int u,int v){edge[++CNT]={v,h[u]};h[u]=CNT;edge[++CNT]={u,h[v]};h[v]=CNT;} int n,m,dfn[MAXN],cnt,ed[MAXN],dep[MAXN],dy[MAXN],p[MAXN]; void dfs(int u,int lst){ dfn[u]=++cnt;dy[cnt]=u; for(inx(u))if(v!=lst){ dep[v]=dep[u]+1; p[v]=-p[u]; dfs(v,u); } ed[u]=cnt; } #define lson pos<<1 #define rson pos<<1|1 struct node{ int x,y,A,B,lza,lzb,lz0; }; struct segtree{ node t[MAXN<<2]; void pushdown(int pos,int l,int r){ if(t[pos].lz0){//cout<<114514<<endl; t[lson].lz0=t[rson].lz0=1; t[lson].x=t[rson].x= t[lson].y=t[rson].y= t[lson].A=t[rson].A= t[lson].B=t[rson].B= t[lson].lza=t[lson].lzb= t[rson].lza=t[rson].lzb= t[pos].lz0=0; } if(t[pos].lza||t[pos].lzb){ int a=t[pos].lza,b=t[pos].lzb; t[lson].lza+=a,t[lson].lzb+=b; t[lson].x+=a; t[lson].y+=b; t[rson].lza+=a,t[rson].lzb+=b; t[rson].x+=a; t[rson].y+=b; t[pos].lza=t[pos].lzb=0; } // cout<<" "<<l<<" "<<r<<" "<<t[lson].x<<" "<<t[lson].y<<" "<<t[rson].x<<" "<<t[rson].y<<endl; } void upd(int pos,int l,int r,int x,int a,int b){ if(l==r){ t[pos].A+=a; t[pos].B+=b; return; } pushdown(pos,l,r); int mid=(l+r)>>1; if(x<=mid)upd(lson,l,mid,x,a,b); else upd(rson,mid+1,r,x,a,b); } void update(int pos,int l,int r,int ql,int qr,int a,int b){ if(ql<=l&&qr>=r){ // cout<<l<<" "<<r<<" "<<a<<" "<<b<<endl; t[pos].lza+=a,t[pos].lzb+=b; t[pos].x+=a; t[pos].y+=b; return; } pushdown(pos,l,r); int mid=(l+r)>>1; if(ql<=mid)update(lson,l,mid,ql,qr,a,b); if(qr>mid)update(rson,mid+1,r,ql,qr,a,b); return; } void update0(int pos,int l,int r,int ql,int qr){ if(ql<=l&&qr>=r){ t[pos].lz0=1; t[pos].x=t[pos].y=t[pos].A=t[pos].B=t[pos].lza=t[pos].lzb=0; return; } pushdown(pos,l,r); int mid=(l+r)>>1; if(ql<=mid)update0(lson,l,mid,ql,qr); if(qr>mid)update0(rson,mid+1,r,ql,qr); return; } int query(int pos,int l,int r,int x){ if(l==r){ return ((t[pos].x+t[pos].y*dep[dy[x]])*p[dy[x]]%Mod+Mod)%Mod; } pushdown(pos,l,r); int mid=(l+r)>>1; if(x<=mid)return query(lson,l,mid,x); if(x>mid)return query(rson,mid+1,r,x); } node queryab(int pos,int l,int r,int x){ if(l==r){ return t[pos]; } pushdown(pos,l,r); int mid=(l+r)>>1; if(x<=mid)return queryab(lson,l,mid,x); if(x>mid)return queryab(rson,mid+1,r,x); } }T; void slv(){ n=read(),m=read(); for(int i=2;i<=n;i++){ int u=read();add_side(u,i); } p[1]=1; dfs(1,1); while(m--){ int opt=read(),x=read(),a,b; if(x<1||x>n)continue; if(opt==1){a=read(),b=read(); T.upd(1,1,n,dfn[x],p[x]*(a-dep[x]*b),p[x]*b); T.update(1,1,n,dfn[x],ed[x],p[x]*(a-dep[x]*b),p[x]*b); } if(opt==2){ printf("%lld\n",T.query(1,1,n,dfn[x])); } if(opt==3){ node tmp=T.queryab(1,1,n,dfn[x]); tmp.x-=tmp.A; tmp.y-=tmp.B; T.update0(1,1,n,dfn[x],ed[x]); T.update(1,1,n,dfn[x],ed[x],tmp.x,tmp.y); } // for(int i=1;i<=n;i++)cout<<T.query(1,1,n,dfn[i])<<" ";cout<<endl; } } signed main(){ slv(); return 0; }