【题解】
本题中的重要思想:区间查询都可以转化为前缀和的差值,还有如何将LCA问题转化为维护树上路径信息的问题
【代码】
#include<stdio.h> #include<stdlib.h> #include<vector> #define MOD 201314 using namespace std; typedef long long LL; vector<int> G[50005],A[50005],N[50005]; int fa[50005]={0},size[50005]={0},son[50005]={0},top[50005]={0},pos[50005]={0},p[50005]={0}; LL sumv[200000]={0},addv[200000]={0},Q[50005][5]={0}; int n,e=0,tot=0; LL jdz(LL x) { if(x<0) x=-x; return x; } void dfs1(int x) { int i; size[x]=1; for(i=0;i<G[x].size();i++) { dfs1(G[x][i]); size[x]+=size[G[x][i]]; if(son[x]==0||size[son[x]]<size[G[x][i]]) son[x]=G[x][i]; } } void dfs2(int x,int t) { int i; top[x]=t; pos[x]=++tot; if(son[x]!=0) dfs2(son[x],t); for(i=0;i<G[x].size();i++) if(G[x][i]!=son[x]) dfs2(G[x][i],G[x][i]); } void xg(LL p,int x,int y,int o,int left,int right) { int mid=(left+right)/2; if(x<=left&&right<=y) addv[o]+=p; else { if(x<=mid) xg(p,x,y,o*2,left,mid); if(y>mid) xg(p,x,y,o*2+1,mid+1,right); } if(left<right) sumv[o]=sumv[o*2]+sumv[o*2+1]+addv[o]*(LL)(right-left+1); else sumv[o]+=p; } LL cx(int x,int y,int o,int left,int right,LL add) { LL ans=0; int mid=(left+right)/2; if(x<=left&&right<=y) return sumv[o]+add*(LL)(right-left+1); add+=addv[o]; if(x<=mid) ans+=cx(x,y,o*2,left,mid,add); if(y>mid) ans+=cx(x,y,o*2+1,mid+1,right,add); return ans; } void update(int x) { int tx=top[x]; while(tx!=0) { xg(1,pos[tx],pos[x],1,1,n); x=fa[tx]; tx=top[x]; } xg(1,pos[0],pos[x],1,1,n); } LL getsum(int x) { LL ans=0; int tx=top[x]; while(tx!=0) { ans=ans+cx(pos[tx],pos[x],1,1,n,0); x=fa[tx]; tx=top[x]; } return ans+cx(pos[0],pos[x],1,1,n,0); } int main() { int q,i,j,l,r,z; scanf("%d%d",&n,&q); for(i=1;i<n;i++) { scanf("%d",&fa[i]); G[fa[i]].push_back(i); } dfs1(0); dfs2(0,0); for(i=1;i<=q;i++) { scanf("%d%d%d",&l,&r,&z); if(l>0) { A[l-1].push_back(z); N[l-1].push_back(i); } A[r].push_back(z); N[r].push_back(i); } for(i=0;i<n;i++) { update(i); for(j=0;j<A[i].size();j++) Q[N[i][j]][++p[N[i][j]]]=getsum(A[i][j]); } for(i=1;i<=q;i++) printf("%lld\n",jdz(Q[i][1]-Q[i][2])%MOD); return 0; }注意最后求答案时Q[i][j]不能是mod过的,否则会导致错误,所以Q[i][j]需定义成long long类型
或者Q[i][j]是mod过的也行,但需要记录这个Q[i][j]属于ans[0,l-1]还是ans[0,r]