提交时间:2024-07-31 11:00:59
运行 ID: 30873
#include<iostream> using namespace std; #define int long long inline int read(){ int i=getchar(),r=0,s=1; while(i<'0'||i>'9'){if(i=='-')s=-1;i=getchar();} while(i>='0'&&i<='9')r=(r<<1)+(r<<3)+(i^48),i=getchar(); return r*s; } const int N=200100,P=1000000007; using pii=pair<int,int>; inline pii operator+(const pii&A,const pii&B){return make_pair((A.first+B.first)%P,(A.second+B.second)%P);} namespace ds{ int rt,ver,ls[N<<1],rs[N<<1],L[N<<1],R[N<<1],laz[N<<1]; pii sum[N<<1]; inline int New(int L_,int R_,int ls_,int rs_){ L[++ver]=L_,R[ver]=R_,ls[ver]=ls_,rs[ver]=rs_; return ver; } int build(int l,int r){ if(l==r)return New(l,r,0,0); int mid=(l+r)>>1; return New(l,r,build(l,mid),build(mid+1,r)); } inline void push_up(int nd){sum[nd]=sum[ls[nd]]+sum[rs[nd]];} inline void push_down(int nd){ if(!laz[nd])return; sum[nd]=make_pair(0ll,0ll); laz[ls[nd]]=laz[rs[nd]]=laz[nd]; laz[nd]=0; } inline void add(int pos,pii k,int nd=rt){ push_down(nd); if(L[nd]==R[nd]){sum[nd]=sum[nd]+k;return;} if(pos<=R[ls[nd]])add(pos,k,ls[nd]); else add(pos,k,rs[nd]); push_down(ls[nd]); push_down(rs[nd]); push_up(nd); } inline pii get_sum(int l,int r,int nd=rt){ push_down(nd); if(l<=L[nd]&&R[nd]<=r)return sum[nd]; pii res=make_pair(0,0); if(l<=R[ls[nd]])res=res+get_sum(l,r,ls[nd]); if(r>=L[rs[nd]])res=res+get_sum(l,r,rs[nd]); return res; } inline void clear(int l,int r,int nd=rt){ push_down(nd); if(l<=L[nd]&&R[nd]<=r){laz[nd]=true;return;} if(l<=R[ls[nd]])clear(l,r,ls[nd]); if(r>=L[rs[nd]])clear(l,r,rs[nd]); push_down(ls[nd]); push_down(rs[nd]); push_up(nd); } } int n,m,son[N],bro[N]; int dep[N],siz[N],hson[N],fa[N]; int top[N],dfn[N]; void dfs1(int nd){ dep[nd]=dep[fa[nd]]+1; siz[nd]=1; for(int i=son[nd];i;i=bro[i]){ fa[i]=nd; dfs1(i); siz[nd]+=siz[i]; if(!hson[nd]||siz[hson[nd]]<siz[i])hson[nd]=i; } } void dfs2(int nd,int top_){ dfn[nd]=++dfn[0]; top[nd]=top_; if(hson[nd])dfs2(hson[nd],top_); for(int i=son[nd];i;i=bro[i])if(i!=fa[nd]&&i!=hson[nd])dfs2(i,i); } void init(){ cin>>n>>m; ds::rt=ds::build(1,n); for(int i=2;i<=n;i++)fa[i]=read(),bro[i]=son[fa[i]],son[fa[i]]=i; dfs1(1); dfs2(1,1); } inline void add(int nd,int a,int b){ if(dep[nd]&1)a=-a,b=-b; a=(a-b*dep[nd])%P; ds::add(dfn[nd],make_pair(a,b)); } inline int get_sum(int nd){ pii res=make_pair(0,0); int p=nd; while(nd){ res=res+ds::get_sum(dfn[top[nd]],dfn[nd]); nd=fa[top[nd]]; } int x=(res.first+res.second*dep[p])%P; if(dep[p]&1)return -x; else return x; } inline void clear(int nd){ ds::clear(dfn[nd],dfn[nd]+siz[nd]-1); } signed main(){ //freopen("tre.in","r",stdin); //freopen("tre.out","w",stdout); init(); while(m--){ int opt=read(),x=read(); // if(x<1||x>n)continue; if(opt==1){ int a=read(),b=read(); add(x,a,b); } else if(opt==2)printf("%lld\n",(get_sum(x)+P)%P); else if(opt==3)clear(x); } return 0; }