传送门

题解

人生第一道由乃……

做这题之前应该先去把这一题给切掉->这里

我的题解->这里

然后先膜一波zsy大佬和flashhu大佬

大体思路就是先吧全0和全1的都跑答案,然后按位贪心

我一开始想到的是每一次split,然后直接一个一个跑

后来发现时间复杂度肯定爆炸……

看了看网上其他的,发现说的都不怎么清楚……结果硬是理解了好久才明白……

先考虑一下LCT维护什么

定义$f0$为全0走过一条路径之后的答案,$f1$表示全1走过一条路径之后的答案

LCT需要维护的是splay中以x为根的子树里,从前往后遍历(即中序遍历)的$f0$和$f1$以及从后往前(即与前面完全相反的顺序)的$f0$和$f1$

比如有一棵splay,x是其中一个点,它在splay中有两个儿子,左儿子y和右儿子z,那么从前往后遍历就是路径y->x->z,从后往前就是路径z->x->y

然后思考,如果已经有了两个区间,该如何合并他们

假如说我们有两段计算出答案的区间,分别对应f0,f1和g0,g1。我们设合并后的答案是h0,h1,那么有如下式子:

$h0=(~f0&g0)+(f0&g1)$

$h1=(~f1&g0)+(f1&g1)$

为啥?

全0走到最后的话,先考虑两种情况

全0走到中间等于1的那几位,走后一半的答案等同于全1走后一半的这几位的答案

全0走到中间等于0的那几位,走后一半的答案等同于全0走后一半的这几位的答案

只需要把这两个答案加起来即可

(ps:这里默认f为前一半的答案,g为后一半的答案)

全1走到最后同理

然后就是几个细节

1.pushdown的时候因为有翻转标记,从前往后走和从后往前走的答案也要交换

2.按位贪心用1做位运算的时候,记得把1设成unsigned long long(简单来说就是设一个ull变量让它等于1)(我就是因为一开始直接用1做位运算结果死都调不出来……)

 // luogu-judger-enable-o2
//minamoto
#include<iostream>
#include<cstdio>
#define ll unsigned long long
using std::swap;
using std::cout;
using std::endl;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline ll read(){
#define num ch-'0'
char ch;bool flag=;ll res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char obuf[<<],*o=obuf;
void print(ll x){
if(x>) print(x/);
*o++=x%+;
}
const int N=;
struct node{
ll f0,f1;
inline node operator +(const node &b)const
{
node a;
a.f0=(~f0&b.f0)|(f0&b.f1);
a.f1=(~f1&b.f0)|(f1&b.f1);
return a;
}
}f[N],l[N],r[N];
int fa[N],ch[N][],s[N],rev[N],top,tot;
int ver[N<<],head[N],Next[N<<];
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot;
}
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
#define ls ch[x][0]
#define rs ch[x][1]
inline void pushup(int x){
l[x]=r[x]=f[x];
if(ls) l[x]=l[ls]+l[x],r[x]=r[x]+r[ls];
if(rs) l[x]=l[x]+l[rs],r[x]=r[rs]+r[x];
}
inline void pushr(int x){
swap(ls,rs),swap(l[x],r[x]),rev[x]^=;
}
inline void pushdown(int x){
if(rev[x]&&x){
pushr(ls),pushr(rs),rev[x]=;
}
}
void rotate(int x){
int y=fa[x],z=fa[y],d=ch[y][]==x;
if(!isroot(y)) ch[z][ch[z][]==y]=x;
fa[x]=z,fa[y]=x,fa[ch[x][d^]]=y,ch[y][d]=ch[x][d^],ch[x][d^]=y,pushup(y);
}
void splay(int x){
s[top=]=x;for(int i=x;!isroot(i);i=fa[i]) s[++top]=fa[i];
while(top) pushdown(s[top--]);
for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
if(!isroot(y))
((ch[y][]==x)^(ch[z][]==y))?rotate(x):rotate(y);
rotate(x);
}
pushup(x);
}
void access(int x){
for(int y=;x;x=fa[y=x]){
splay(x),rs=y,pushup(x);
}
}
void makeroot(int x){
access(x),splay(x),pushr(x);
}
void split(int x,int y){
makeroot(x),access(y),splay(y);
}
void dfs(int u){
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v==fa[u]) continue;
fa[v]=u,dfs(v);
}
pushup(u);
}
int main(){
//freopen("testdata.in","r",stdin);
int n=read(),m=read(),k=read();
for(int i=;i<=n;++i){
int x=read();ll y=read();
switch(x){
case :f[i]=(node){,y};break;
case :f[i]=(node){y,~};break;
case :f[i]=(node){y,~y};break;
}
}
for(int i=;i<n;++i){
int u=read(),v=read();add(u,v);
}
dfs();
while(m--){
int opt=read(),x=read(),y=read();ll z=read();
if(opt&){
split(x,y);ll ans=,e=;
for(int i=k-;i>=;--i){
if(l[y].f0&(e<<i)) ans|=e<<i;
else if((l[y].f1&(e<<i))&&z>=(e<<i)) ans|=e<<i,z^=e<<i;
}
print(ans),*o++='\n';
}
else{
switch(y){
case :f[x]=(node){,z};break;
case :f[x]=(node){z,~};break;
case :f[x]=(node){z,~z};break;
}
splay(x);
}
}
fwrite(obuf,o-obuf,,stdout);
return ;
}

洛谷P3613 睡觉困难综合征的更多相关文章

  1. 【刷题】洛谷 P3613 睡觉困难综合征

    题目背景 刚立完Flag我就挂了WC和THUWC... 时间限制0.5s,空间限制128MB 因为Claris大佬帮助一周目由乃通过了Deus的题,所以一周目的由乃前往二周目世界找雪辉去了 由于二周目 ...

  2. 洛谷P3613 睡觉困难综合征(LCT)

    题目: P3613 睡觉困难综合症 解题思路: LCT,主要是维护链上的多位贪心答案,推个公式:分类讨论入0/1的情况,合并就好了(公式是合并用的) 代码(我不知道之前那个为啥一直wa,改成结构体就好 ...

  3. 洛谷P3613 睡觉困难综合征(LCT,贪心)

    洛谷题目传送门 膜拜神犇出题人管理员!!膜拜yler和ZSY!! 没错yler连续教我这个蒟蒻写起床困难综合症和睡觉困难综合症%%%Orz,所以按位贪心的思路可以继承下来 这里最好还是写树剖吧,不过我 ...

  4. [洛谷]P3613 睡觉困难综合征

    题目大意:给出一棵n个点的树,每个点有一个运算符(与.或.异或)和一个数,支持两种操作,第一种修改一个点的运算符和数,第二种给出x,y,z,询问若有一个0~z之间的数从点x走到点y(简单路径),并且对 ...

  5. [洛谷P3613]睡觉困难综合症

    写码30min,调码3h的题.. 好在最后查出来了 , , n, x, y, z); 改成了 , , n, mark[x], y, z); 然后$40\rightarrow 100$ #include ...

  6. 洛谷3613睡觉困难综合征(LCT维护链信息(前后缀)+贪心)

    这个题目还是很好啊QWQ很有纪念意义 首先,如果在序列上且是单次询问的话,就是一个非常裸的贪心了QWQ这也是NOI当时原题的问题和数据范围 我们考虑上树的话,应该怎么做? 我的想法是,对于每一位建一个 ...

  7. [bzoj3668][Noi2014]起床困难综合症/[洛谷3613]睡觉困难综合症

    来自FallDream的博客,未经允许,请勿转载,谢谢. 21 世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳.作为一名青春阳光好少年,atm 一直坚持与起床困难综 ...

  8. P3613 睡觉困难综合征(LCT + 位运算)

    题意 NOI2014 起床困难综合症 放在树上,加上单点修改与链上查询. 题解 类似于原题,我们只需要求出 \(0\) 和 \(2^{k - 1} - 1\) 走过这条链会变成什么值,就能确定每一位为 ...

  9. [P3613]睡觉困难综合征

    Description: 给定一个n个点的树,每个点有一个操作符号 "&" "|" "^" ,以及一个权值 要求支持以下操作: 1. ...

随机推荐

  1. ssh框架,工具类调用service层方法

    解决方法: @Component//声明为spring组件 public class CopyFileUtil{ @Autowired private DataFileManager dataFile ...

  2. 06.Lucen入门程序-Field

    需求: 实现一个歌词搜索系统,通过关键字搜索,凡是文件名或文件内容包括关键字的文件都要找出来. 注意:该入门程序只对文本文件(.txt)搜索. Lucene中包含两个重要的类: IndexWriter ...

  3. 【BZOJ 3261】最大异或和【可持久化字典树】

    题意 给出一个长度为n的整数序列,给出m个操作.操作有两种.1,Ax表示在序列结尾增加x.2,Qlrx表示找到一个位置p满足 l<=p<=r,使得a[p] xor a[p+1]xor... ...

  4. HQL多表查询

    ------------------siwuxie095 HQL 多表查询 以客户和联系人为例(一对多) 1.内连接 (1)hql 语句写法 from Customer c inner join c. ...

  5. jquery入门 修改网页背景颜色

    我们在浏览一些网站,尤其是一些小说网站的时候,都会有修改页面背景颜色的地方,这个功能使用jquery很容易实现. 效果图: show you code: <!doctype html> & ...

  6. 微信小程序开发教程,大多数人都搞错的八个问题

    小程序目前被炒得沸沸扬扬,无数媒体和企业借机获取阅读流量. 这再次证明一点,微信想让什么火,真的就能让什么火.这种能力真是全中国再也没有人有了,政府也没有. 但四处传的消息很多是失真的,废话不说,先列 ...

  7. vim全局替换命令-乾颐堂

    语法为 :[addr]s/源字符串/目的字符串/[option] 全局替换命令为::%s/源字符串/目的字符串/g [addr] 表示检索范围,省略时表示当前行. 如:“1,20” :表示从第1行到2 ...

  8. AspnetBoilerplate (ABP) Organization Units 组织结构管理

    ABP是一个成熟的.NET框架,功能完善.目前由于项目需要正在自学中. ABP对于组织节点管理这一基本上每个项目都要反复重复开发的内容,进行了自己的实现. 主要包括这些常用功能: 多租户 树结构管理的 ...

  9. RF和GBDT的区别

    Random Forest ​采用bagging思想,即利用bootstrap抽样,得到若干个数据集,每个数据集都训练一颗树. 构建决策树时,每次分类节点时,并不是考虑全部特征,而是从特征候选集中选取 ...

  10. 完全卸载memcached的方法(CentOS)

    前阵子给服务器装了个memcached,4G的内存,想给网站提提速,实际上不但没有明显效果,反倒耗费内存,看着碍眼,于是想卸载,网上各种搜索+自己实践,搞出一个傻瓜方案来: 1.首先查找你的memca ...