题目大意:一棵树,q个操作,a,b,c,当a=1时树上b-c节点权值+1,a=2,求b-c节点的权值和。
题解:树剖
pushdown的时候没有乘以懒标记orz
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstring> #include<cstdio> #define maxn 500008 using namespace std; int n,q,sumedge,cnt; int head[maxn],dad[maxn],top[maxn],deep[maxn],size[maxn],tpos[maxn]; struct Tree{ int l,r,sum,s; }tr[maxn<<2]; struct Edge{ int x,y,nxt; Edge(int x=0,int y=0,int nxt=0): x(x),y(y),nxt(nxt){} }edge[maxn<<1]; void add(int x,int y){ edge[++sumedge]=Edge(x,y,head[x]); head[x]=sumedge; } void pushup(int rt){ tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum; return; } void pushdown(int rt){ if(!tr[rt].s)return; tr[rt<<1].s+=tr[rt].s;tr[rt<<1].sum+=(tr[rt<<1].r-tr[rt<<1].l+1)*tr[rt].s; tr[rt<<1|1].s+=tr[rt].s;tr[rt<<1|1].sum+=(tr[rt<<1|1].r-tr[rt<<1|1].l+1)*tr[rt].s; tr[rt].s=0;return; } void build(int rt,int l,int r){ tr[rt].l=l;tr[rt].r=r; if(l==r)return; int mid=(l+r)>>1; build(rt<<1,l,mid);build(rt<<1|1,mid+1,r); return; } int query_sum(int rt,int l,int r,int ql,int qr){ pushdown(rt); if(l>=ql&&r<=qr){ return tr[rt].sum; } int ans=0,mid=(l+r)>>1; if(ql<=mid)ans+=query_sum(rt<<1,l,mid,ql,qr); if(qr>mid)ans+=query_sum(rt<<1|1,mid+1,r,ql,qr); return ans; } void change(int rt,int l,int r,int ql,int qr){ pushdown(rt); if(l>=ql&&r<=qr){ tr[rt].sum+=(tr[rt].r-tr[rt].l+1); tr[rt].s++; return; } int mid=(l+r)>>1; if(ql<=mid)change(rt<<1,l,mid,ql,qr); if(qr>mid)change(rt<<1|1,mid+1,r,ql,qr); pushup(rt); } void dfs(int x){ size[x]=1;deep[x]=deep[dad[x]]+1; for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].y; if(v==dad[x])continue; dad[v]=x;dfs(v); size[x]+=size[v]; } } void dfs_(int x){ int s=0;tpos[x]=++cnt; if(!top[x])top[x]=x; for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].y; if(v!=dad[x]&&size[v]>size[s])s=v; } if(s){ top[s]=top[x]; dfs_(s); } for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].y; if(v!=dad[x]&&v!=s)dfs_(v); } } int lca(int x,int y){ for(;top[x]!=top[y];){ if(deep[top[x]]>deep[top[y]])swap(x,y); y=dad[top[y]]; } if(deep[x]>deep[y])return y; return x; } void query(int x,int y){ int ret=0; for(;top[x]!=top[y];){ if(deep[top[x]]>deep[top[y]])swap(x,y); ret+=query_sum(1,1,n,tpos[top[y]],tpos[y]); y=dad[top[y]]; } if(deep[x]>deep[y])swap(x,y); ret+=query_sum(1,1,n,tpos[x],tpos[y]); printf("%d ",ret); } void change_(int x,int y){ for(;top[x]!=top[y];){ if(deep[top[x]]>deep[top[y]])swap(x,y); change(1,1,n,tpos[top[y]],tpos[y]); y=dad[top[y]]; } if(deep[x]>deep[y])swap(x,y); change(1,1,n,tpos[x],tpos[y]); } int main(){ scanf("%d",&n); for(int i=1;i<n;i++){ int x,y; scanf("%d%d",&x,&y); add(x,y);add(y,x); } dfs(1);dfs_(1);build(1,1,n); scanf("%d",&q); for(int i=1;i<=q;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); if(a==1)change_(b,c); else query(b,c); } return 0; }