• Ynoi2017 由乃的OJ


    Link
    这题以前叫睡觉困难综合征。
    首先我们需要知道起床困难综合征怎么做。
    大概就是先用一个全(0)和全(1)的变量跑一遍处理出每一位(1)(0)最后会变成什么。
    然后高位贪心:如果当前位能够从(0)(1),那么直接选上。如果能够从(1)(0),那么能选就选。
    现在我们把它放到了树上。
    那么使用LCT或者树剖就可以解决了。

    #include<bits/stdc++.h>
    #define N 100007
    #define ull unsigned long long
    using namespace std;
    namespace IO
    {
        char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[22],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
        char Get() { return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++); }
        void Flush() { fwrite(obuf,1,oS-obuf,stdout),oS=obuf; }
        void Put(char x) { *oS++=x; if(oS==oT) Flush(); }
        ull read(){ull x=0;char ch=Get();while(ch>'9'||ch<'0')ch=Get();while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=Get();return x;}
        void write(ull x){int top=0;if(!x)return (void)Put('0'),Put('
    ');while(x)st[++top]=(x%10)+48,x/=10;while(top)Put(st[top--]);Put('
    ');}
    }
    using namespace IO;
    struct node{ull f0,f1;}val[N],lr[N],rl[N];
    node merge(node x,node y){return (node){(~x.f0&y.f0)|(x.f0&y.f1),(~x.f1&y.f0)|(x.f1&y.f1)};}
    int fa[N],ch[N][2],r[N];
    #define lc ch[p][0]
    #define rc ch[p][1]
    int nroot(int p){return ch[fa[p]][0]==p||ch[fa[p]][1]==p;}
    void pushup(int p)
    {
        lr[p]=rl[p]=val[p];
        if(lc) lr[p]=merge(lr[lc],lr[p]),rl[p]=merge(rl[p],rl[lc]);
        if(rc) lr[p]=merge(lr[p],lr[rc]),rl[p]=merge(rl[rc],rl[p]);
    }
    void pushrev(int p){swap(lr[p],rl[p]),swap(lc,rc),r[p]^=1;}
    void pushdown(int p){if(r[p])pushrev(lc),pushrev(rc),r[p]=0;}
    void pushall(int p){if(nroot(p))pushall(fa[p]);pushdown(p);}
    void rotate(int p)
    {
        int x=fa[p],y=fa[x],k=ch[x][1]==p,w=ch[p][!k];
        if(nroot(x)) ch[y][ch[y][1]==x]=p;
        ch[p][!k]=x,ch[x][k]=w,fa[w]=x,fa[x]=p,fa[p]=y,pushup(x);
    }
    void splay(int p)
    {    
        pushall(p);
        for(int x;nroot(p);rotate(p))if(nroot(x=fa[p])) rotate((ch[x][0]==p)^(ch[fa[x]][0]==x)? p:x);
        pushup(p);
    }
    void access(int p){for(int x=0;p;p=fa[x=p])splay(p),rc=x,pushup(p);}
    void makeroot(int p){access(p),splay(p),pushrev(p);}
    void split(int u,int v){makeroot(u),access(v),splay(v);}
    void link(int u,int v){makeroot(u),fa[u]=v;}
    ull query(ull w,int v,int u)
    {
        ull ans=0,tmp=1;split(u,v);
        for(int k=63;~k;--k)
            if(lr[v].f0&(tmp<<k)) ans+=(tmp<<k);
            else if(lr[v].f1&(tmp<<k)&&w>=(tmp<<k)) w-=(tmp<<k),ans+=(tmp<<k);
        return ans;
    }
    int main()
    {
        int n=read(),m=read(),i,u,v;read();
        ull e=0,x;
        for(i=1;i<=n;++i)
    	switch(read())
    	{
    	case 1:val[i]=(node){e,read()};break;
    	case 2:val[i]=(node){read(),~e};break;
    	case 3:x=read(),val[i]=(node){x,~x};break;
    	}
        for(i=1;i<n;++i) u=read(),v=read(),link(u,v);
        while(m--)
        {
    	
    	if(read()==1) write(query(read(),read(),read()));
    	else
    	{
    	    u=read();
    	    switch(read())
    	    {
    	    case 1:val[u]=(node){e,read()};break;
    	    case 2:val[u]=(node){read(),~e};break;
    	    case 3:x=read(),val[u]=(node){x,~x};break;
    	    }
    	    splay(u);
    	}
        }
        return Flush(),0;
    }
    
  • 相关阅读:
    计算两个时间相差几个月
    批量生成二维码
    PHP实现二维数组(或多维数组)转换成一维数组
    任意二维数组转换成一维数组
    企业微信的使用与公众号以及其它几个应用的使用方式都是一致的
    判断字符类型
    insert一个表的数据到另外一个表
    同步a表的数据到 b表
    PHP Curl Accept-Encoding: gzip乱码问题解决
    spring boot入门程序
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11913645.html
Copyright © 2020-2023  润新知