In mathematics you don't understand things, you just get used to them.

Description

Link.

起床困难综合症 上树。

Solution

线段树维护,树剖上树。

具体题解有空再写,我要去睡觉了。

#include<bits/stdc++.h>
typedef unsigned long long ULL;
struct node {
    ULL one,zero;
    node(ULL A=0,ULL B=0) {
        one=A;
        zero=B;
    }
}nodes[400010],exnodes[400010],res,exres;
ULL poi[100010],opz;
int k,dep[100010],son[100010],hb[100010],fa[100010],dfn[100010],sjc,op[100010],n,m,rev[100010],siz[100010];
int head[100010],nxt[200010],to[200010],cntot,opt,opx,opy;
bool flag,exflag;
void addEdge(int one,int ano) {
    to[++cntot]=ano;
    nxt[cntot]=head[one];
    head[one]=cntot;
}
node merge(node one,node ano) {
    node res(~0ull);
    ULL tmp=one.one,extmp=~tmp;
    res.one=(tmp&ano.one)|(extmp&ano.zero);
    tmp=one.zero;
    extmp=~tmp;
    res.zero=(tmp&ano.one)|(extmp&ano.zero);
    return res;
}
void adj(ULL &x,ULL y,int id) {
    if(id==1) {
        x&=y;
    } else if(id==2) {
        x|=y;
    } else {
        x^=y;
    }
}
void build(int l,int r,int x) {
    if(l^r) {
        int mid=(l+r)>>1;
        build(l,mid,x<<1);
        build(mid+1,r,x<<1|1);
        nodes[x]=merge(nodes[x<<1],nodes[x<<1|1]);
        exnodes[x]=merge(exnodes[x<<1|1],exnodes[x<<1]);
    } else {
        nodes[x]=exnodes[x]=node(~0ull);
        adj(nodes[x].one,poi[rev[l]],op[rev[l]]);
        adj(nodes[x].zero,poi[rev[l]],op[rev[l]]);
        adj(exnodes[x].one,poi[rev[l]],op[rev[l]]);
        adj(exnodes[x].zero,poi[rev[l]],op[rev[l]]);
    }
}
void ins(int l,int r,int x,int pos,int aj,ULL val) {
    if(l^r) {
        int mid=(l+r)>>1;
        if(mid>=pos) {
            ins(l,mid,x<<1,pos,aj,val);
        } else {
            ins(mid+1,r,x<<1|1,pos,aj,val);
        }
        nodes[x]=merge(nodes[x<<1],nodes[x<<1|1]);
        exnodes[x]=merge(exnodes[x<<1|1],exnodes[x<<1]);
    } else {
        op[rev[l]]=aj;
        poi[rev[l]]=val;
        nodes[x]=exnodes[x]=node(~0ull);
        adj(nodes[x].one,poi[rev[l]],op[rev[l]]);
        adj(nodes[x].zero,poi[rev[l]],op[rev[l]]);
        adj(exnodes[x].one,poi[rev[l]],op[rev[l]]);
        adj(exnodes[x].zero,poi[rev[l]],op[rev[l]]);
    }
}
void find(int l,int r,int x,int fr,int ba) {
    if(l>ba || r<fr) {
        return;
    } else {
        if(l>=fr && r<=ba) {
            if(!flag) {
                res=nodes[x];
                flag=true;
            } else {
                res=merge(nodes[x],res);
            }
        } else {
            int mid=(l+r)>>1;
            find(mid+1,r,x<<1|1,fr,ba);
            find(l,mid,x<<1,fr,ba);
        }
    }
}
void exfind(int l,int r,int x,int fr,int ba) {
    if(l>ba || r<fr) {
        return;
    } else {
        if(l>=fr && r<=ba) {
            if(!exflag) {
                exres=exnodes[x];
                exflag=true;
            } else {
                exres=merge(exres,exnodes[x]);
            }
        } else {
            int mid=(l+r)>>1;
            exfind(mid+1,r,x<<1|1,fr,ba);
            exfind(l,mid,x<<1,fr,ba);
        }
    }
}
node LCA(int x,int y) {
    flag=exflag=false;
    res=exres=node(~0ull);
    while(hb[x]^hb[y]) {
        if(dep[hb[x]]>dep[hb[y]]) {
            exfind(1,n,1,dfn[hb[x]],dfn[x]);
            x=fa[hb[x]];
        } else {
            find(1,n,1,dfn[hb[y]],dfn[y]);
            y=fa[hb[y]];
        }
    }
    if(dep[x]<dep[y]) {
        find(1,n,1,dfn[x],dfn[y]);
    } else {
        exfind(1,n,1,dfn[y],dfn[x]);
    }
    return merge(exres,res);
}
void dfs1(int x,int las) {
    dep[x]=dep[las]+1;
    fa[x]=las;
    siz[x]=1;
    for(int i=head[x];i;i=nxt[i]) {
        int y=to[i];
        if(y^las) {
            dfs1(y,x);
            siz[x]+=siz[y];
            if(siz[son[x]]<siz[y]) {
                son[x]=y;
            }
        }
    }
}
void dfs2(int x,int t) {
    hb[x]=t;
    dfn[x]=++sjc;
    rev[sjc]=x;
    if(son[x]) {
        dfs2(son[x],t);
        for(int i=head[x];i;i=nxt[i]) {
            int y=to[i];
            if((y^fa[x]) && (y^son[x])) {
                dfs2(y,y);
            }
        }
    }
}
ULL solve(node now,ULL lim) {
    ULL res=0,run=0;
    for(int i=k-1;~i;--i) {
        if(now.zero&(1ull<<i)) {
            res+=(1ull<<i);
        } else if((now.one&(1ull<<i)) && run+(1ull<<i)<=lim) {
            run+=(1ull<<i);
            res+=(1ull<<i);
        }
    } 
    return res;
}
char fgc() {
    static char buf[1<<21],*p=buf,*q=buf;
    return p==q && (q=buf+fread(p=buf,1,1<<21,stdin),p==q)?EOF:*p++;
}
template<typename T>
void read(T &hhh) {
    T x=0;
    int f=0;
    char c=fgc();
    while(c<'0' || c>'9') {
        if(c=='-') {
            f=1;
        }
        c=fgc();
    }
    while(c>='0' && c<='9') {
        x=(x<<3)+(x<<1)+(c^'0');
        c=fgc();
    }
    if(f) {
        hhh=-x;
    } else {
        hhh=x;
    }
}
int wrstk[100];
template<typename T>
void write(T x,char las='\n') {
    int top=0,f=0;
    if(x<0) {
        x=-x;
        f=1;
    }
    do {
        wrstk[++top]=x%10;
        x/=10;
    } while(x);
    if(f) {
        putchar('-');
    }
    while(top) {
        putchar(wrstk[top--]^'0');
    }
    putchar(las);
}
int main() {
    read(n);
    read(m);
    read(k);
    for(int i=1;i<=n;++i) {
        read(op[i]);
        read(poi[i]);
    }
    for(int i=1,x,y;i<n;++i) {
        read(x);
        read(y);
        addEdge(x,y);
        addEdge(y,x);
    }
    dfs1(1,0);
    dfs2(1,1);
    build(1,n,1);
    while(m-->0) {
        read(opt);
        read(opx);
        read(opy);
        read(opz);
        if(opt==1) {
            if(k) {
                write(solve(LCA(opx,opy),opz));
            } else {
                write(0);
            }
        } else {
            ins(1,n,1,dfn[opx],opy,opz);
        }
    }
    return 0;
}

data structures trees bitwise

Solution -「洛谷 P6156」简单题
Prev «
Journey -「CQOI 2021」
» Next