社区讨论

树链剖分WA on 6求调

CF343DWater Tree参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mhk7286o
此快照首次捕获于
2025/11/04 14:34
4 个月前
此快照最后确认于
2025/11/04 14:34
4 个月前
查看原帖
rt
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=100010;
int n,m,w[N],vl[N];
int dfn[N],lastdfn[N];
vector<int> v[N];

namespace segment{
    int tree[N<<2],tag[N<<2];
    int ls(int xx){
        return xx*2;
    }
    int rs(int xx){
        return xx*2+1;
    }
    void pushup(int now){
        tree[now]=tree[ls(now)]+tree[rs(now)];
    }
    void add_tag(int now,int l,int r,int val){
        tree[now]=val*(r-l+1);
        tag[now]=val;
    }
    void pushdown(int now,int l,int r){
        if(tag[now]==-1) return;
        int mid=(l+r)>>1;
        add_tag(ls(now),l,mid,tag[now]);
        add_tag(rs(now),mid+1,r,tag[now]);
        tag[now]=-1;
    }
    void build(int now,int l,int r){
        tag[now]=-1;
        if(l==r){
            tree[now]=vl[l];
            return;
        }
        int mid=(l+r)>>1;
        build(ls(now),l,mid);
        build(rs(now),mid+1,r);
        pushup(now);
    }
    void update(int now,int l,int r,int ll,int rr,int val){
        if(l>=ll && r<=rr){
            add_tag(now,l,r,val);
            return;
        }
        int mid=(l+r)>>1;
        pushdown(now,l,r);
        if(ll<=mid) update(ls(now),l,mid,ll,rr,val);
        if(rr>mid) update(rs(now),mid+1,r,ll,rr,val);
        pushup(now);
    }
    int query(int now,int l,int r,int ll,int rr){
        if(l>=ll && r<=rr){
            return tree[now];
        }
        int mid=(l+r)>>1;
        int res=0;
        pushdown(now,l,r);
        if(ll<=mid) res+=query(ls(now),l,mid,ll,rr);
        if(rr>mid) res+=query(rs(now),mid+1,r,ll,rr);
        pushup(now);
        return res;
    }
}

namespace tree_pou{
    int cnt,siz[N],son[N],father[N],dep[N],top[N];
    void get_son(int x,int fa,int d){
        siz[x]=1;
        father[x]=fa;
        dep[x]=d;
        int maxsize=0;
        for(int i=0;i<v[x].size();i++){
            int to=v[x][i];
            if(to==fa) continue;
            get_son(to,x,d+1);
            siz[x]+=siz[to];
            if(siz[to]>maxsize){
                maxsize=siz[to],son[x]=to;
            }
        }
    }
    void dfs(int x,int fa){
        dfn[x]=lastdfn[x]=++cnt;
        if(x==1) top[x]=x;
        if(son[x]){
            top[son[x]]=top[x];
            dfs(son[x],x);
            lastdfn[x]=max(lastdfn[x],lastdfn[son[x]]);
        }
        for(int i=0;i<v[x].size();i++){
            int to=v[x][i];
            if(to==fa || to==son[x]) continue;
            top[to]=to;
            dfs(to,x);
            lastdfn[x]=max(lastdfn[x],lastdfn[to]);
        }
    }
    int get_ans(int x,int y){
        int ans=0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            ans+=segment::query(1,1,n,dfn[top[x]],dfn[x]);
            //cout<<"real: "<<x<<" "<<top[x]<<"\n";
            x=father[top[x]];
        }
        if(dep[y]<dep[x]) swap(x,y);
        //cout<<"real: "<<x<<" "<<y<<"\n";
        ans+=segment::query(1,1,n,dfn[x],dfn[y]);
        return ans;
    }
    void update(int x,int y,int z){
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            segment::update(1,1,n,dfn[top[x]],dfn[x],z);
            x=father[top[x]];
        }
        if(dep[y]<dep[x]) swap(x,y);
        segment::update(1,1,n,dfn[x],dfn[y],z);
    }
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<n;i++){
        int x,y;
        cin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    tree_pou::get_son(1,0,1);
    tree_pou::dfs(1,0);
    for(int i=1;i<=n;i++) vl[dfn[i]]=w[i];//,cout<<"i: "<<i<<" "<<dfn[i]<<" "<<lastdfn[i]<<"\n";
    //for(int i=1;i<=n;i++) cout<<"i: "<<i<<" "<<vl[dfn[i]]<<"\n";
    segment::build(1,1,n);
    cin>>m;
    //for(int i=1;i<=n;i++) cout<<"i: "<<i<<" "<<segment::query(1,1,n,dfn[i],dfn[i])<<" "<<dfn[i]<<"\n";
    while(m--){
        int opt,x,y,z;
        cin>>opt;
        if(opt==1){
            cin>>x;
            segment::update(1,1,n,dfn[x],lastdfn[x],1);
        }
        else if(opt==2){
            cin>>x;
            tree_pou::update(dfn[1],dfn[x],0);
        }
        else if(opt==3){
            cin>>x;
            //cout<<"x: "<<dfn[x]<<"\n";
            cout<<segment::query(1,1,n,dfn[x],dfn[x])<<"\n";
        }
    }
    return 0;
}

回复

4 条回复,欢迎继续交流。

正在加载回复...