ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

bzoj 4811 由乃的OJ

2019-02-21 08:49:04  阅读:323  来源: 互联网

标签:4811 OJ res1 long merge dfn ull op bzoj


bzoj 4811 由乃的OJ

  • 考虑树链剖分.
  • 树剖后用一颗线段树维护一段连续区间,类似于一个函数,各位上进入 \(0/1\) ,输出的数字分别是什么.注意到最多只有 \(64\) 位,可以用一个 \(unsigned\ long\ long\) 的大数状压表示,合并两段区间时推导一下可以做到 \(O(1)\) .
  • 注意 \(3 种\)位运算混在一起,满足交换律,却不满足结合律,所以从区间左/右侧进入同一个数,最后得到的数不同.需要维护两个方向的函数.
  • 修改时在线段树上单点修改就好,查询用树剖的基本操作,先找出 \(x\to y\) 这一段的函数,再贪心构造解.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
typedef unsigned long long ull;
ull read(){
    ull nm=0,fh=1;char cw=getchar();
    for(;!isdigit(cw);cw=getchar()) ;
    for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
    return nm*fh;
}
const int MAXN=2e5+10;
ull cnt=0,head[MAXN],to[MAXN<<1],nx[MAXN<<1];
inline void addedge(ull u,ull v)
{
    ++cnt;
    to[cnt]=v;
    nx[cnt]=head[u];
    head[u]=cnt;
}
inline void ins(ull u,ull v)
{
    addedge(u,v);
    addedge(v,u);
}
const unsigned long long U1=1;
ull fa[MAXN],siz[MAXN],mxson[MAXN],top[MAXN],dfn[MAXN],rnk[MAXN],dep[MAXN],idx=0;
void dfs1(ull u)
{
    siz[u]=U1;
    dep[u]=dep[fa[u]]+U1;
    for(ull i=head[u];i>0;i=nx[i])
        {
            ull v=to[i];
            if(v==fa[u])
                continue;
            fa[v]=u;
            dfs1(v);
            siz[u]+=siz[v];
            if(siz[v]>siz[mxson[u]])
                mxson[u]=v;
        }
}
void dfs2(ull u,ull Tp)
{
    dfn[u]=++idx;
    rnk[idx]=u;
    top[u]=Tp;
    if(mxson[u]>0)
        dfs2(mxson[u],Tp);
    for(ull i=head[u];i>0;i=nx[i])
        {
            ull v=to[i];
            if(v==fa[u] || v==mxson[u])
                continue;
            dfs2(v,v);
        }
}
inline ull calc(ull x,ull bas,ull op)
{
    if(op==1)
        return x&bas;
    if(op==2)
        return x|bas;
    return x^bas;
}
ull val[MAXN],opt[MAXN];
unsigned long long maxv=0;
struct node{
    ull l,r;
    ull d[2][2];//d[左入/右入][全0/全1] 
    void init(ull v,ull op)
        {
            d[0][0]=d[1][0]=calc(0,v,op);
            d[0][1]=d[1][1]=calc(maxv,v,op);
        }
    void merge(node L,node R)
        {       
            d[0][0]=(L.d[0][0]&R.d[0][1])|((~L.d[0][0])&R.d[0][0]);
            d[1][0]=(R.d[1][0]&L.d[1][1])|((~R.d[1][0])&L.d[1][0]);
            d[0][1]=(L.d[0][1]&R.d[0][1])|((~L.d[0][1])&R.d[0][0]);
            d[1][1]=(R.d[1][1]&L.d[1][1])|((~R.d[1][1])&L.d[1][0]);
        }
    void inverse()
        {
            swap(d[0][0],d[1][0]);
            swap(d[0][1],d[1][1]);
        }
};
struct SegmentTree{
    #define root Tree[o]
    #define lson Tree[o<<1]
    #define rson Tree[o<<1|1]
    node Tree[MAXN<<2];
    void BuildTree(ull o,ull l,ull r)
        {
            root.l=l,root.r=r;
            if(l==r)
                {
                    root.init(val[rnk[l]],opt[rnk[l]]);
                    return;
                }
            ull mid=(l+r)>>1;
            BuildTree(o<<1,l,mid);
            BuildTree(o<<1|1,mid+1,r);
            root.merge(lson,rson);
        }
    void update(ull o,ull pos,ull newv,ull newopt)
        {
            ull l=root.l,r=root.r;
            if(l==r)
                {
                    root.init(newv,newopt);
                    return;
                }
            ull mid=(l+r)>>1;
            if(pos<=mid)
                update(o<<1,pos,newv,newopt);
            else
                update(o<<1|1,pos,newv,newopt);
            root.merge(lson,rson);
        }
    node query(ull o,ull L,ull R)
        {
            ull l=root.l,r=root.r;
            if(L<=l && r<=R)
                return root;
            node res;
            res.init(0,3);
            if(l>R || r<L)
                return res;
            res.merge(query(o<<1,L,R),query(o<<1|1,L,R));
            return res;
        }
}T;
ull n,m,k;
void init()
{
    ull rt=(n+1)>>1;
    fa[rt]=0;
    for(ull i=0;i<k;i++) 
        maxv+=(U1<<i);
    dfs1(rt);
    dfs2(rt,rt);
    T.BuildTree(1,1,n);
}
ull solve(ull x,ull y,ull lim)
{
    ull tot=0;
    node res1,res2,cur;
    res1.init(0,3);
    res2.init(0,3);
    while(top[x]!=top[y])
        {
            if(dep[top[x]]>dep[top[y]])
                {
                    res1.merge(T.query(1,dfn[top[x]],dfn[x]),res1);
                    x=fa[top[x]];
                }
            else
                {
                    res2.merge(T.query(1,dfn[top[y]],dfn[y]),res2);
                    y=fa[top[y]];
                }
        }
    if(dep[x]>dep[y])
        {
            node c=T.query(1,dfn[y],dfn[x]);
            res1.merge(c,res1);
        }       
    else
        {
            node c=T.query(1,dfn[x],dfn[y]);
            res2.merge(c,res2);
        }
    res1.inverse();
    cur.merge(res1,res2);
    for(ull i=k;i-->0;)
        {
            if(cur.d[0][0] & (U1<<i))
                tot+=(U1<<i);
            else if( ( (cur.d[0][1]) & (U1<<i) ) >0 && lim>=(U1<<i) )
                lim-=(U1<<i),tot+=(U1<<i);
        }
    return tot;
}
int main()
{
    n=read(),m=read(),k=read();
    for(ull i=1;i<=n;++i)
        opt[i]=read(),val[i]=read();
    for(ull i=1;i<n;++i)
        {
            ull u=read(),v=read();
            ins(u,v);
        }
    init();
    while(m--)
        {
            ull op=read();
            ull x=read(),y=read(),z=read();
            if(op==1)
                cout<<solve(x,y,z)<<endl;
            else
                T.update(1,dfn[x],z,y);
        }
    return 0;
}

标签:4811,OJ,res1,long,merge,dfn,ull,op,bzoj
来源: https://www.cnblogs.com/jklover/p/10410285.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有