直接维护按照顺序经过每一段,初始的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\n",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;
}
}
}

  

BZOJ 4811 [Ynoi2017]由乃的OJ ——Link-Cut Tree的更多相关文章

  1. bzoj 4811: [Ynoi2017]由乃的OJ

    树链剖分,用zkw线段树维护每条链两个方向上对每一位的变换情况,由于位数较少,可以用两个unsigned long long表示 #include<cstdio> typedef unsi ...

  2. [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)

    [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...

  3. link cut tree 入门

    鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...

  4. Link Cut Tree学习笔记

    从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...

  5. Codeforces Round #339 (Div. 2) A. Link/Cut Tree 水题

    A. Link/Cut Tree 题目连接: http://www.codeforces.com/contest/614/problem/A Description Programmer Rostis ...

  6. Link/cut Tree

    Link/cut Tree 一棵link/cut tree是一种用以表示一个森林,一个有根树集合的数据结构.它提供以下操作: 向森林中加入一棵只有一个点的树. 将一个点及其子树从其所在的树上断开. 将 ...

  7. 洛谷P3690 Link Cut Tree (模板)

    Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...

  8. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  9. bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门

    link cut tree入门题 首先说明本人只会写自底向上的数组版(都说了不写指针.不写自顶向下QAQ……) 突然发现link cut tree不难写... 说一下各个函数作用: bool isro ...

随机推荐

  1. ios 自定义加载动画效果

    在开发过程中,可能会遇到各种不同的场景需要等待加载成功后才能显示数据.以下是自定义的一个动画加载view效果.      在UIViewController的中加载等到效果,如下 - (void)vi ...

  2. 纯css实现div三列等高布局的最简单方法简化版/也可以多列

    使用正padding和负margin对冲实现多列布局方法 这种方法很简单,就是在所有列中使用正的上.下padding和负的上.下margin,并在所有列外面加上一个容器,并设置overflow:hid ...

  3. selenium-Python之定位下拉框选择

    1.通过select 进行定位下拉框 下拉框如图所示 通过代码定位 #通过index进行选择Select(driver.find_element_by_id("cardType") ...

  4. kafka 安装以及测试

    1,下载kafka 并进行解压 http://mirrors.cnnic.cn/apache/kafka/0.8.1.1/kafka_2.9.2-0.8.1.1.tgz 2,启动Zookeeper  ...

  5. python_112_网络编程 Socket编程

    实例1:客户端发小写英文,服务器端返回给客户端大写英文(仅支持一次接受发送) 服务器端: #服务器端(先于客户端运行) import socket server=socket.socket() ser ...

  6. Shift-Invariant论文笔记

    ICML 2019 Making Convolutional Networks Shift-Invariant Again ICML 2019 Making Convolutional Network ...

  7. C04 模块化开发

    目录 模块化开发概述 函数概述 如何使用函数 字符串处理函数 模块化开发特点 模块化开发概述 概述 C语言是面向过程的语言,意味着编写C语言程序的时候,我们要像计算机一样思考如何设计程序. 模块化开发 ...

  8. luogu P2574 XOR的艺术 (线段树)

    luogu P2574 XOR的艺术 (线段树) 算是比较简单的线段树. 当区间修改时.\(1 xor 1 = 0,0 xor 1 = 1\)所以就是区间元素个数减去以前的\(1\)的个数就是现在\( ...

  9. Linux运维发展与学习路线图

    记录一下Linux所要懂的知识体系,方便未来学习的时候自我验证. Linux运维课程体系大纲: Linux入门 了解Linux基础,知道什么是Linux,会安装Linux,使用相关基础命令,如:cd, ...

  10. requests库的学习——跟随官方文档

    发送GET请求: import requests r=requests.get("http://www.kekenet.com/") 如果需要传递参数可以有以下几种方法: impo ...