1. 程式人生 > 實用技巧 >瑪卡巴卡

瑪卡巴卡

#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;
}