• bzoj4811


    题解:

    对于每一个节点,我们建立v0,v1

    v0表示0进过会怎么样

    v1表示1进过会怎么样

    然后线段树合并

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=100005;
    typedef unsigned long long ull;
    ull a[N],zz,now,ans;
    int n,m,k,op,xx,yy,Op[N],fi[N],ne[N*2],v[N*2],tot;
    int size[N],fa[N],son[N],deep[N],rev[N],dfn[N],cnt,top[N];
    struct Tree
    {
        ull v0,v1;Tree(){}
        Tree(int op,ull x)
         {
             if (op==1)v0=0,v1=x;
            else if (op==2)v0=x,v1=~0;
            else v0=x,v1=(~0)^x;
         }
        Tree(ull x,ull y){v0=x,v1=y;}
    }trl[N*8],trr[N*8];
    Tree operator+(Tree x,Tree y)
    {
        return Tree((x.v0&y.v1)|((~x.v0)&y.v0),(x.v1&y.v1)|((~x.v1)&y.v0));
    }
    void jb(int x,int y)
    {
        v[tot]=y;
        ne[tot]=fi[x];
        fi[x]=tot++;
    }
    void dfs1(int x)
    {
        size[x]=1;
        for (int i=fi[x];~i;i=ne[i])
         if (v[i]!=fa[x])
          {
            fa[v[i]]=x;
            deep[v[i]]=deep[x]+1;
            dfs1(v[i]);
            size[x]+=size[v[i]];
            if (size[v[i]]>size[son[x]])son[x]=v[i];
          }
    }
    void dfs2(int x,int tp)
    {
        rev[dfn[x]=++cnt]=x;
        top[x]=tp;
        if (son[x])dfs2(son[x],tp);
        for (int i=fi[x];~i;i=ne[i])
         if (v[i]!=fa[x]&&v[i]!=son[x])dfs2(v[i],v[i]);
    }
    void build(int l,int r,int pos)
    {
        if (l==r)
         {
             trl[pos]=trr[pos]=Tree(Op[rev[l]],a[rev[l]]);
            return;
          }
        int mid=(l+r)>>1;
        build(l,mid,pos*2);
        build(mid+1,r,pos*2+1);
        trl[pos]=trl[pos*2]+trl[pos*2+1];
        trr[pos]=trr[pos*2+1]+trr[pos*2];
    }
    void insert(int l,int r,int pos,int num)
    {
        if (l==r)
         {
             trl[pos]=trr[pos]=Tree(Op[rev[l]],a[rev[l]]);
            return;
         }
        int mid=(l+r)>>1;
        if (mid<num)insert(mid+1,r,pos*2+1,num);
        else insert(l,mid,pos*2,num);
        trl[pos]=trl[pos*2]+trl[pos*2+1];
        trr[pos]=trr[pos*2+1]+trr[pos*2];
    }
    Tree query(int l,int r,int pos,int L,int R,int f)
    {
        if (l>=L&&r<=R)return f?trr[pos]:trl[pos];
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if (mid<L)return query(mid+1,r,pos*2+1,L,R,f);
        if (mid>=R)return query(l,mid,pos*2,L,R,f);
        if (!f)return query(l,mid,pos*2,L,R,f)+query(mid+1,r,pos*2+1,L,R,f);
        return query(mid+1,r,pos*2+1,L,R,f)+query(l,mid,pos*2,L,R,f);
    }
    Tree solve(int x,int y)
    {
        Tree vx=Tree((int)3,0ull),vy=Tree((int)3,0ull);
        int fx=top[x],fy=top[y];
        while (fx!=fy)
         if (deep[fx]>deep[fy])
          {
              vx=vx+query(1,n,1,dfn[fx],dfn[x],1);
            x=fa[fx];
            fx=top[x];
          }
         else 
          {    
              vy=query(1,n,1,dfn[fy],dfn[y],0)+vy;
            y=fa[fy];
            fy=top[y];
          }
        if (deep[x]>deep[y])return vx+query(1,n,1,dfn[y],dfn[x],1)+vy;
        return vx+query(1,n,1,dfn[x],dfn[y],0)+vy;
    }
    int main()
    {
        memset(fi,-1,sizeof(fi));
        deep[1]=1;
        scanf("%d%d%d",&n,&m,&k);
        for (int i=1;i<=n;i++)scanf("%d%llu",&Op[i],&a[i]);
        for (int i=1;i<n;i++)
         {
             scanf("%d%d",&xx,&yy);
            jb(xx,yy);jb(yy,xx);
         }
        dfs1(1);dfs2(1,1); 
        build(1,n,1);
        while (m--)
         {
            scanf("%d%d%d%llu",&op,&xx,&yy,&zz);
            if (op==2)Op[xx]=yy,a[xx]=zz,insert(1,n,1,dfn[xx]);
            else
             {
                 Tree t=solve(xx,yy);now=ans=0;
                for (int i=k-1;~i;i--)
                 if (t.v0&(1ull<<i))ans+=1ull<<i;
                 else if (t.v1&(1ull<<i)&&now+(1ull<<i)<=zz)
                  {
                      now+=1ull<<i;
                    ans+=1ull<<i;
                  }
                printf("%llu
    ",ans);
             }
         }
        return 0; 
    }
  • 相关阅读:
    P3723 【[AH2017/HNOI2017]礼物】
    P4555 【[国家集训队]最长双回文串】
    manacher学习笔记
    多项式学习笔记
    题解 CF1097F 【Alex and a TV Show】
    docker数据卷容器
    python基础学习
    docker监控之cadvisor
    docker监控系统
    ssh配置详解及公私钥批量分发
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8010645.html
Copyright © 2020-2023  润新知