树链剖分

    xiaoxiao2022-07-16  156

    #include<cstdio> #include<iostream> #include<cstring> using namespace std; const int MAXM=1000010,MAXN=1000010; struct Edge{ int from,to,nxt; }e[MAXM]; int head[MAXN],edgeCnt=0; void addEdge(int u,int v){ e[++edgeCnt].from=u; e[edgeCnt].to=v; e[edgeCnt].nxt=head[u]; head[u]=edgeCnt; } int n; int dep[MAXN],fa[MAXN],size[MAXN]; int son[MAXN]; void dfs1(int x){ size[x]=1; dep[x]=dep[fa[x]]+1; for(int i=head[x];i;i=e[i].nxt){ int v=e[i].to; if(v!=fa[x]){ fa[v]=x; dfs1(v); size[x]+=size[v]; if(size[v]>size[son[x]])son[x]=v; } } } int top[MAXN],id[MAXN],idCnt=0; int initValue[MAXN],nowValue[MAXN]; void dfs2(int x){ if(x==son[fa[x]])top[x]=top[fa[x]]; else top[x]=x; id[x]=++idCnt; nowValue[idCnt]=initValue[x]; if(son[x])dfs2(son[x]); for(int i=head[x];i;i=e[i].nxt){ int v=e[i].to; if(v!=son[x]&&v!=fa[x]){ dfs2(v); } } } struct node{ int ls,rs; int lazy; long long sum; }tr[MAXN]; int nodeCnt=0; void insert(int &now,int l,int r,int ll,int rr,int x){ if(!now)now=++nodeCnt; int b=min(r,rr)-max(l,ll)+1; tr[now].sum+=x*b; if(l>=ll&&r<=rr){ tr[now].lazy+=x; return; } int mid=(l+r)>>1; if(ll<=mid)insert(tr[now].ls,l,mid,ll,rr,x); if(rr>mid)insert(tr[now].rs,mid+1,r,ll,rr,x); } long long query(int now,int l,int r,int ll,int rr){ if(l>=ll&&r<=rr)return tr[now].sum; int mid=(l+r)>>1; if(tr[now].lazy){ if(!tr[now].ls)tr[now].ls=++nodeCnt; tr[tr[now].ls].lazy+=tr[now].lazy; tr[tr[now].ls].sum+=(mid-l+1)*tr[now].lazy; if(!tr[now].rs)tr[now].rs=++nodeCnt; tr[tr[now].rs].lazy+=tr[now].lazy; tr[tr[now].rs].sum+=(r-mid)*tr[now].lazy; tr[now].lazy=0; } long long ans=0; if(ll<=mid)ans+=query(tr[now].ls,l,mid,ll,rr); if(rr>mid)ans+=query(tr[now].rs,mid+1,r,ll,rr); return ans; } int root=0; void change(int u,int v,int w){ while(top[u]!=top[v]){ if(dep[top[u]]<dep[top[v]])swap(u,v); insert(root,1,n,id[top[u]],id[u],w); u=fa[top[u]]; } if(dep[u]>dep[v])swap(u,v); insert(root,1,n,id[u],id[v],w); } int mod; long long sum(int u,int v){ long long ans=0; while(top[u]!=top[v]){ if(dep[top[u]]<dep[top[v]])swap(u,v); ans+=query(root,1,n,id[top[u]],id[u]); u=fa[top[u]]; } if(dep[u]>dep[v])swap(u,v); ans+=query(root,1,n,id[u],id[v]); return ans%mod; } int main(){ int m,r; scanf("%d%d%d%d",&n,&m,&r,&mod); for(int i=1;i<=n;i++){ scanf("%d",&initValue[i]); } for(int i=1;i<=n-1;i++){ int u,v; scanf("%d%d",&u,&v); addEdge(u,v); addEdge(v,u);//双向 } dfs1(r); dfs2(r); for(int i=1;i<=n;i++){ insert(root,1,n,id[i],id[i],nowValue[id[i]]); } for(int i=1;i<=m;i++){ int opt,x,y,z; scanf("%d%d",&opt,&x); switch(opt){ case 1: scanf("%d%d",&y,&z); change(x,y,z); break; case 2: scanf("%d",&y); printf("%lld\n",sum(x,y)); break; case 3: scanf("%d",&z); insert(root,1,n,id[x],id[x]+size[x]-1,z); break; case 4: printf("%lld\n",query(root,1,n,id[x],id[x]+size[x]-1)%mod); break; } } return 0; }

     

    最新回复(0)