树剖求条样例过了 0分 又RE又WA又TLE
查看原帖
树剖求条样例过了 0分 又RE又WA又TLE
338144
tkth楼主2023/10/18 09:26
#include <iostream>
#define int long long 
#define ls (x<<1)
#define rs (x<<1|1)
using namespace std;
const int N = 1e6+10;
int n,m,dis[N],tlc,trc;
int dep[N],dfn[N],rnk[N],son[N],siz[N],top[N],fa[N],tot;
struct EDGE
{
    int Head[N*2],Ver[N*2],Next[N*2],tot;
    inline void add(int x,int y){
        Ver[++tot]=y,Next[tot]=Head[x],Head[x]=tot;
    }
}E;
namespace lineTree
{
    struct Tree
    {
        int l,r,num,lc,rc,tag;
    }t[N*4];
    inline void pushUp(int x)
    {
        t[x].lc=t[ls].lc,t[x].rc=t[rs].rc;
        if(t[ls].rc==t[rs].lc) t[x].num=t[ls].num+t[rs].num-1;
        else t[x].num=t[ls].num+t[rs].num;
    } 
    void build(int x,int l,int r)
    {
        t[x].l=l,t[x].r=r;
        if(l==r){
            t[x].lc=t[x].rc=dis[rnk[l]];
            t[x].num=1;
            return;
        }
        int mid=l+r>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        pushUp(x);
        return;
    }
    inline void pushDown(int x)
    {
        if(t[x].tag){
            t[ls].tag=t[rs].tag=t[x].tag;
            t[ls].lc=t[ls].rc=t[x].tag;
            t[ls].num=1;
            t[rs].lc=t[rs].rc=t[x].tag;
            t[rs].num=1;
            t[x].tag=0;
        }
    }
    void update(int x,int l,int r,int num)
    {
        if(t[x].l >= l&&t[x].r <= r){
            t[x].lc=t[x].rc=num;
            t[x].num=1;
            t[x].tag=num;
            return;
        }
        pushDown(x);
        int mid=t[x].l+t[x].r>>1;
        if(mid >= l) update(ls,l,r,num);
        if(mid < r) update(rs,l,r,num);
        pushUp(x);
        return;
    }
    int getNum(int x,int l,int r)
    {
        if(t[x].l>=l&&t[x].r<=r){
            if(tlc==0){
                tlc=t[x].lc,trc=t[x].rc;
                return t[x].num;
            }
            else if(trc != t[x].lc){
                trc=t[x].rc;return t[x].num;
            }
            else if(trc==t[x].lc){
                trc=t[x].rc;return t[x].num-1;
            }
        }
        pushDown(x);
        int mid=t[x].l+t[x].r>>1,ans=0;
        if(mid >= l) ans+=getNum(ls,l,r);
        if(mid < r) ans+=getNum(rs,l,r);
        return ans;
    }
}
void dfs1(int x,int f)
{
    siz[x]=1;
    for(int i = E.Head[x];i;i=E.Next[i]){
        int y=E.Ver[i];
        if(y==f) continue;
        fa[y]=x;
        dep[y]=dep[x]+1;
        dfs1(y,x);
        siz[x]+=siz[y];
        if(siz[son[x]]<siz[y]) son[x]=y;
    }
}
void dfs2(int x,int t)
{
    top[x]=t;
    dfn[x]=++tot;
    rnk[tot]=x;
    if(!son[x])return;
    dfs2(son[x],t);
    for(int i = E.Head[x];i;i=E.Next[i]){
        int y=E.Ver[i];
        if(y==fa[x]||y==son[x])continue;
        dfs2(y,y);
    }
}
inline void pathChange(int x,int y,int num)
{
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        lineTree::update(1,dfn[top[x]],dfn[x],num);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    lineTree::update(1,dfn[x],dfn[y],num);
    return;
}
inline int pathNum(int x,int y)
{
    int ans=0,lrc=0,llc=0;
    while(top[x]!=top[y]){
        tlc=0,trc=0;
        if(dep[top[x]]<dep[top[y]]) swap(x,y),swap(lrc,llc);
        ans+=lineTree::getNum(1,dfn[top[x]],dfn[x]);
        if(lrc==trc) ans-=1;
        lrc=tlc;
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y),swap(llc,lrc);
    tlc=0,trc=0;
    ans+=lineTree::getNum(1,dfn[x],dfn[y]);;
    if(llc==trc) ans-=1;
    if(lrc==tlc)ans-=1;
    return ans;
}
inline int read(){
    int num=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        num=(num<<1)+(num<<3)+(c^48);
        c=getchar();
    }
    return num*f;
}
signed main(){
    n=read(),m=read();
    for(int i = 1;i <= n;i++) dis[i]=read();
    for(int i = 1;i < n;i++){
        int x=read(),y=read();
        E.add(x,y);
        E.add(y,x);
    }
    dfs1(1,0);
    dfs2(1,1);
    lineTree::build(1,1,n);
    while(m--){
        char c=getchar();
        if(c=='C'){
            int x=read(),y=read(),z=read();
            pathChange(x,y,z);
        }
        else{
            int x=read(),y=read();
            printf("%lld\n",pathNum(x,y));
        }
    }
    return 0;
}

测评记录:林克

2023/10/18 09:26
加载中...