zoukankan      html  css  js  c++  java
  • BZOJ 4811 [Ynoi2017]由乃的OJ ——Link-Cut Tree

    直接维护按照顺序经过每一段,初始的1可以变成什么,初始为0可以变成什么。

    然后答案就可以和起床困难综合征一样贪心处理了。

    写起来并不好写。

    发现交换左右子树之后答案会改变,GG

    调了一天,最后还是T掉了

    肝败吓疯

    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define L ch[x][0]
    #define R ch[x][1]
    #define ll unsigned long long 
    #define mp make_pair
    #define maxn 400005 
     
    int n,m,k; ll all;
     
    namespace Link_Cut_Tree{
        int ch[maxn][2],fa[maxn];
        int rev[maxn];
        int opt[maxn],sta[maxn],top=0;
        ll num[maxn],tag1[maxn],tag0[maxn],revtag0[maxn],revtag1[maxn];
        void print(int x)
        {D(i,k-1,0) {printf("%d",(x>>i)&1);if (i==0) break;}}
        ll Maker(ll tmp,int opt,ll x)
        {
            switch(opt)
            {
                case 1: return tmp&x; break;
                case 2: return tmp|x; break;
                case 3: return tmp^x; break;
            }
        }
        void pushdown(int k);
        void update(int x)
        {
            if (rev[L]&&rev[R])
            {
                tag1[x]=(Maker(revtag1[R],opt[x],num[x])&revtag1[L])|((~Maker(revtag1[R],opt[x],num[x]))&revtag0[L]);
                tag0[x]=(Maker(revtag0[R],opt[x],num[x])&revtag1[L])|((~Maker(revtag0[R],opt[x],num[x]))&revtag0[L]);
                revtag1[x]=(Maker(tag1[L],opt[x],num[x])&tag1[R])|((~Maker(tag1[L],opt[x],num[x]))&tag0[R]);
                revtag0[x]=(Maker(tag0[L],opt[x],num[x])&tag1[R])|((~Maker(tag0[L],opt[x],num[x]))&tag0[R]);
            }
            else if (rev[L])
            {
                tag1[x]=(Maker(tag1[R],opt[x],num[x])&revtag1[L])|((~Maker(tag1[R],opt[x],num[x]))&revtag0[L]);
                tag0[x]=(Maker(tag0[R],opt[x],num[x])&revtag1[L])|((~Maker(tag0[R],opt[x],num[x]))&revtag0[L]);
                revtag1[x]=(Maker(tag1[L],opt[x],num[x])&revtag1[R])|((~Maker(tag1[L],opt[x],num[x]))&revtag0[R]);
                revtag0[x]=(Maker(tag0[L],opt[x],num[x])&revtag1[R])|((~Maker(tag0[L],opt[x],num[x]))&revtag0[R]);
            }
            else if (rev[R])
            {
                tag1[x]=(Maker(revtag1[R],opt[x],num[x])&tag1[L])|((~Maker(revtag1[R],opt[x],num[x]))&tag0[L]);
                tag0[x]=(Maker(revtag0[R],opt[x],num[x])&tag1[L])|((~Maker(revtag0[R],opt[x],num[x]))&tag0[L]);
                revtag1[x]=(Maker(revtag1[L],opt[x],num[x])&tag1[R])|((~Maker(revtag1[L],opt[x],num[x]))&tag0[R]);
                revtag0[x]=(Maker(revtag0[L],opt[x],num[x])&tag1[R])|((~Maker(revtag0[L],opt[x],num[x]))&tag0[R]);
            }
            else
            {
                tag1[x]=(Maker(tag1[R],opt[x],num[x])&tag1[L])|((~Maker(tag1[R],opt[x],num[x]))&tag0[L]);
                tag0[x]=(Maker(tag0[R],opt[x],num[x])&tag1[L])|((~Maker(tag0[R],opt[x],num[x]))&tag0[L]);
                revtag1[x]=(Maker(revtag1[L],opt[x],num[x])&revtag1[R])|((~Maker(revtag1[L],opt[x],num[x]))&revtag0[R]);
                revtag0[x]=(Maker(revtag0[L],opt[x],num[x])&revtag1[R])|((~Maker(revtag0[L],opt[x],num[x]))&revtag0[R]);
            }
        }  
        bool isroot(int k)
        {return ch[fa[k]][0]!=k&&ch[fa[k]][1]!=k;}
        void pushdown(int k)
        {
            if (rev[k])
            {
                rev[k]^=1;
                rev[ch[k][0]]^=1;
                rev[ch[k][1]]^=1;
                swap(ch[k][0],ch[k][1]);
                if (rev[ch[k][0]]) pushdown (ch[k][0]);
                update(k);
            }
        }
        void rot(int x)
        {
            int y=fa[x],z=fa[y],l,r;
            if (ch[y][0]==x) l=0; else l=1;
            r=l^1;
            if (!isroot(y))
            {
                if (ch[z][0]==y) ch[z][0]=x;
                else ch[z][1]=x;
            }
            fa[x]=z; fa[y]=x; fa[ch[x][r]]=y;
            ch[y][l]=ch[x][r]; ch[x][r]=y;
            update(y); update(x);
        }
        void splay(int x)
        {
            top=0; sta[++top]=x;
            for (int i=x;!isroot(i);i=fa[i]) sta[++top]=fa[i];
            while (top) pushdown(sta[top--]);
            while (!isroot(x))
            {
                int y=fa[x],z=fa[y];
                if (!isroot(y))
                {
                    if ((ch[y][0]==x)^(ch[z][0]==y)) rot(x);
                    else rot(y);
                }
                rot(x);
            }
        }
        void access(int x)
        {for (int t=0;x;t=x,x=fa[x])splay(x),ch[x][1]=t,update(x);}
        void makeroot(int x)
        {access(x); splay(x); rev[x]^=1;}
        int find(int x)
        {
            access(x);
            splay(x);
            while (ch[x][0]) x=ch[x][0];
            return x;
        }
        void cut(int x,int y)
        {
            makeroot(x);
            access(y);
            splay(y);
            if (ch[y][0]==x) ch[y][0]=fa[x]=0;
            update(y);
        }
        void link(int x,int y)
        {
            makeroot(x);
            fa[x]=y;
        }
        void modify(int x,int op,ll xi)
        {access(x);splay(x);opt[x]=op;num[x]=xi;update(x);}
        void query(int x,int y,ll z)
        {
            makeroot(y);access(x);splay(x);
            ll ret=0,ans=0;
            for (int i=k-1;i>=0;--i)
            {
                if ((((tag1[x]>>i)&1LLu)==1LLu)&&(((tag0[x]>>i)&1LLu)==0))
                {if ((ans|(1LLu<<i))<=z) ans|=1LLu<<i,ret|=1LLu<<i;}
                else if ((((tag0[x]>>i)&1LLu)==1LLu)) ret|=1LLu<<i;
            }
            printf("%llu
    ",ret);
        }
        void init(int k)
        {tag1[0]=all;tag0[0]=0;revtag1[0]=all; revtag0[0]=0;opt[0]=1;num[0]=all;}
    }
     
    using namespace Link_Cut_Tree;
     
    int Getint()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
     
    ll Getull()
    {
        ll x=0; char ch=getchar();
        while (ch<'0'||ch>'9')ch=getchar();
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x;
    }
     
    int main()
    {
        n=Getint(); m=Getint(); k=Getint();
        F(i,0,k-1) all|=(1LLu<<i); init(k); 
        F(i,1,n)
            opt[i]=Getint(),num[i]=Getull();
        F(i,2,n)
        {
            int a,b;
            a=Getint(); b=Getint();
            link(a,b);
        }
        F(i,1,m)
        {
            int Q,x,y;ll z;
            Q=Getint(); x=Getint(); y=Getint(); z=Getull();
            switch(Q)
            {
                case 1: query(x,y,z); break;
                case 2: modify(x,y,z);break;
            }
        }
    }
    

      

  • 相关阅读:
    【数据结构】线性表&&顺序表详解和代码实例
    【智能算法】超详细的遗传算法(Genetic Algorithm)解析和TSP求解代码详解
    【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)
    【智能算法】迭代局部搜索(Iterated Local Search, ILS)详解
    10. js时间格式转换
    2. 解决svn working copy locked问题
    1. easyui tree 初始化的两种方式
    10. js截取最后一个斜杠后面的字符串
    2. apache整合tomcat部署集群
    1. apache如何启动
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6736923.html
Copyright © 2011-2022 走看看