瑪卡巴卡
阿新 • • 發佈:2020-08-02
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1e4+1; int head[maxn],top[maxn],dfn[maxn],size[maxn],son[maxn],f[maxn],rk[maxn],a[maxn],cnt=0,len=0,n,m,deep[maxn]; struct E1{int len,sum,l,r,tag;}tree[maxn<<2]; struct E{int to,next,w;}e[maxn<<1]; void In(int x,int y){e[++len].to=y;e[len].next=head[x];head[x]=len;} void Dfs1(int u,int fa){ size[u]=1; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(v==fa)continue; f[v]=u; deep[v]=deep[u]+1; Dfs1(v,u); size[u]+=size[v]; if(!son[u]||size[v]>size[son[u]]) son[u]=v; } } void Dfs2(int u,int tp){ top[u]=tp; dfn[u]=++cnt; rk[cnt]=a[u]; if(son[u])Dfs2(son[u],tp); for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(v!=f[u]&&v!=son[u]) Dfs2(v,v); } } void Build(int i,int l,int r){ tree[i].l=l;tree[i].r=r;tree[i].len=r-l+1; if(l==r){ tree[i].sum=0; return; } int mid=(l+r)>>1; Build(i<<1,l,mid);Build(i<<1|1,mid+1,r); tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum; } void push_down(int i){ if(tree[i].tag){ tree[i<<1].tag+=tree[i].tag; tree[i<<1|1].tag+=tree[i].tag; tree[i<<1].sum+=tree[i<<1].len*tree[i].tag; tree[i<<1|1].sum+=tree[i<<1|1].len*tree[i].tag; tree[i].tag=0; } } void TreeAdd(int i,int l,int r,int k){ if(tree[i].r<l||tree[i].l>r)return ; if(tree[i].l>=l&&tree[i].r<=r){ tree[i].sum+=k; tree[i].tag+=k; return ; } push_down(i); if(tree[i<<1].r>=l)TreeAdd(i<<1,l,r,k); if(tree[i<<1|1].l<=r)TreeAdd(i<<1|1,l,r,k); tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum; } void WayAdd(int u,int v){ while(top[u]!=top[v]){ if(deep[top[u]]<deep[top[v]])swap(u,v); TreeAdd(1,dfn[top[u]],dfn[u],1); u=f[top[u]]; } if(deep[u]>deep[v])swap(u,v); TreeAdd(1,dfn[u]+1,dfn[v],1); } int TreeQ(int i,int l,int r){ int ans=0; push_down(i); if(tree[i].r<l||tree[i].l>r)return 0; if(tree[i].l>=l&&tree[i].r<=r){ return tree[i].sum; } if(tree[i<<1].r>=l)ans+=TreeQ(i<<1,l,r); if(tree[i<<1|1].l<=r)ans+=TreeQ(i<<1|1,l,r); // printf("%d %d QWQ=%d\n",tree[i].sum,i,ans); return ans; } int WayQ(int u,int v){ int ans=0; while(top[u]!=top[v]){ if(deep[top[u]]<deep[top[v]])swap(u,v); ans=max(ans,TreeQ(1,dfn[top[u]],dfn[u])); u=f[top[u]]; } if(deep[u]>deep[v])swap(u,v); ans=max(ans,TreeQ(1,dfn[u]+1,dfn[v])); return ans; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<n;i++){ int x,y;scanf("%d%d",&x,&y); In(x,y);In(y,x); } Dfs1(1,0);Dfs2(1,1);Build(1,1,n); //for(int i=1;i<=8;i++)printf("%d %d\n",i,tree[i].sum); for(int i=1;i<=m;i++){ char c;scanf(" %c",&c); if(c=='P'){ int x,y;scanf("%d%d",&x,&y); TreeAdd(1,x,y,1); } //for(int i=1;i<=8;i++)printf("%c %d %d\n",c,i,tree[i].sum); if(c=='Q'){ int x,y;scanf("%d%d",&x,&y); //if(deep[x]<deep[y])swap(x,y); printf("%d\n",WayQ(x,y)); } } return 0; }