Description

给定一棵 \(n\) 个点的树,每个点上有位运算 \(opt\) 和一个权值 \(x\),位运算有 &,|,^ 三种。

要求支持:

  1. 修改点 \(v\) 的 \(opt\) 和 \(x_v\)
  2. 确定一个初始点权在 \([0,z]\) 之间的 \(v_0\),然后依次经过从 \(x\) 到 \(y\) 的所有节点。每经过一个节点 \(i\), \(v\) 就变成 \(v\;opt\;x_i\) 请回答最后到 \(y\) 时可能的最大的 \(v\) 。

Solution

首先五十分的做法比较显然,就是拆位建 \(lct\),然后每位分开做,复杂度 \(O(nk\log n)\)。

这样只有 \(50\) 分,考虑优化复杂度。

因为 \(O(n\log n)\) 已经是 \(lct\) 的复杂度了不是很能优化掉,考虑去掉复杂度乘上的 \(k\)。

有这个 \(k\) 的原因是我们对于每一位都搞了棵 \(lct\) 出来。如果我们只弄一棵 \(lct\) 是否可行呢?

定义 \(f0,f1\) 分别为初始值全 \(0/1\) 走过一条路径之后的答案

那在 \(lct\) 中需要维护的就是 \(splay\) 里 \(x\) 的子树,中序遍历的 \(f0,f1\) 已经倒着的中序遍历(与中序遍历相反)\(f0,f1\) (要维护这个倒着的原因是当前点 \(x\) 的值与左右子树的顺序有关,而 \(splay\) 中又有 \(reverse\) 操作所以要维护)。

那有了这个能不能快速更新呢?也就是说有左区间的 \(f0,f1\) 和右区间的 \(g0,g1\),能不能快速求出来 \(h0,h1\) 呢?废话

更新式子比较显然就是:\(h0=(f0\&g1)+(\sim f0\& g0),h1=(f1\And g1)+(\sim f1\& g0)\)

证明的话就是全 \(0\) 放进去左区间之后跑出来的是 \(f0\),可能长 \(10010001010\) 这样,然后再去 $\And $ 一下 \(g1\) 就代表这些当前为 \(1\) 的位放进右区间之后跑出来的是多少。因为 \(\&\) 了 \(f0\) 所以最后答案肯定不会比 \(f0\) 大。其它几项的证明也类似就不去证了。

最后求出来 从 \(x\) 到 \(y\) 的 \(f0,f1\) 之后贪心的选就好了。

Code

#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cctype>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using std::min;
using std::max;
using std::swap;
using std::vector;
typedef double db;
typedef unsigned long long ll;
#define pb(A) push_back(A)
#define pii std::pair<int,int>
#define all(A) A.begin(),A.end()
#define mp(A,B) std::make_pair(A,B) namespace NewweN{ const int N=1e5+5; int n,m,cnt,head[N],stk[N],top;
int fa[N],ch[N][2],tag[N],k;ll maxn;
char buf[1048578];int ptr,MX;
#define ls ch[x][0]
#define rs ch[x][1] struct Edge{
int to,nxt;
}edge[N<<1]; void add(int x,int y){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
head[x]=cnt;
} struct Node{
ll a,b;
Node(){}
Node(ll x,ll y){
a=x,b=y;
}
friend Node operator+(Node x,Node y){
return Node((x.a&y.b)+(((~x.a))&y.a),(x.b&y.b)+(((~x.b))&y.a));
}
}l[N],r[N],val[N]; char nc(){
if(ptr==MX) MX=fread(buf,1,1<<20,stdin),ptr=0;
return ptr==MX?EOF:buf[ptr++];
}
#define getchar nc
ll getint(){
ll X=0,w=0;char ch=getchar();
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while( isdigit(ch))X=X*10+ch-48,ch=getchar();
if(w) return -X;return X;
} void dfs(int now,int f=0){
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==f)continue;
fa[to]=now;
dfs(to,now);
}
} void pushup(int x){
l[x]=r[x]=val[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];
} void pushr(int x){
tag[x]^=1;swap(ls,rs);swap(l[x],r[x]);
} void pushdown(int x){
if(tag[x])tag[x]=0,pushr(ls),pushr(rs);
} bool nroot(int x){
return ch[fa[x]][0]==x or ch[fa[x]][1]==x;
} void rotate(int x){
int y=fa[x],z=fa[y],d=ch[y][1]==x,dd=ch[z][1]==y;
ch[y][d]=ch[x][d^1];if(ch[x][d^1])fa[ch[x][d^1]]=y;
fa[x]=z;if(nroot(y))ch[z][dd]=x;
fa[y]=x;ch[x][d^1]=y;pushup(y);
} void splay(int x){
int now=x;stk[++top]=now;
while(nroot(now))now=fa[now],stk[++top]=now;
while(top)pushdown(stk[top--]);
while(nroot(x)){
int y=fa[x],z=fa[y];
if(nroot(y))rotate((ch[y][1]==x)^(ch[z][1]==y)?x:y);
rotate(x);
}pushup(x);
} void access(int x){
for(int y=0;x;y=x,x=fa[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);
} signed main(){
n=getint(),m=getint(),k=getint();
maxn=(1ull<<k)-1;
for(int i=1;i<=n;i++){
ll x=getint(),y=getint();
if(x==1)val[i]=Node(0,y);
if(x==2)val[i]=Node(y,~0);
if(x==3)val[i]=Node(y,(~y));
}
for(int i=1;i<n;i++){
int x=getint(),y=getint();
add(x,y),add(y,x);
} dfs(1);
while(m--){
int opt=getint(),x=getint(),y=getint();ll z=getint();
if(opt==1){
split(x,y);
ll ans=0,used=0;
for(int i=k-1;~i;i--){
if(l[y].a>>i&1ull) ans|=1ull<<i;
else if((l[y].b>>i&1ull) and (used|(1ull<<i))<=z) ans|=1ull<<i,used|=1ull<<i;
} printf("%llu\n",ans);
} else{
splay(x);
if(y==1) val[x]=Node(0,z);
if(y==2) val[x]=Node(z,~0);
if(y==3) val[x]=Node(z,(~z));
pushup(x);
}
} return 0;
}
} int yzh=NewweN::main(); signed main(){return 0;}

[Luogu 3613] 睡觉困难综合征的更多相关文章

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

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

  2. Luogu 睡觉困难综合征 ([NOI2014]起床困难综合症)

    一.[NOI2014]起床困难综合症 题目描述 网址:https://daniu.luogu.org/problemnew/show/2114 大意: 有一条链,链上每一个节点包含一个位运算f 与 一 ...

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

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

  4. 省队集训Day1 睡觉困难综合征

    传送门:https://www.luogu.org/problem/show?pid=3613 [题解] 按二进制位分开,对于每一位,用“起床困难综合征”的方法贪心做. 写棵LCT,维护正反两种权值, ...

  5. Luogu3613 睡觉困难综合征/BZOJ4811 Ynoi2017 由乃的OJ 树链剖分、贪心

    传送门 题意:给出一个$N$个点的树,树上每个点有一个位运算符号和一个数值.需要支持以下操作:修改一个点的位运算符号和数值,或者给出两个点$x,y$并给出一个上界$a$,可以选取一个$[0,a]$内的 ...

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

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

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

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

  8. Luogu3613 睡觉困难综合征

    题面描述https://www.luogu.org/problemnew/show/3613 原题NOI2014起床困难综合症https://www.luogu.org/problemnew/show ...

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

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

随机推荐

  1. PyCharm选择性忽略PEP8代码风格警告信息

    用了几天的PyCharm,发现确实在编写Python代码上非常好用,但有一点体验不太好,就是代码编写时要按照PEP8代码风格编写,不然会有波浪线的警告信息.解决方法如下: 方法一: 将鼠标移到提示的地 ...

  2. tensorflow学习之(六)使用tensorboard展示神经网络的graph

    # 创建神经网络, 使用tensorboard 展示graph import tensorflow as tf import numpy as np import matplotlib.pyplot ...

  3. delphi 中record 的类操作符重载简介

    今天简单介绍一下 delphi 中record 的类操作符重载使用,就是如何 实现 record 之间的简单操作. 关于类操作符重载 ,大家可以看官方的文档. Delphi allows certai ...

  4. (22)Embrace the near win

    https://www.ted.com/talks/sarah_lewis_embrace_the_near_win/transcript?referrer=playlist-talks_to_get ...

  5. shp文件和地理数据库文件的区别

    存储文件结构不同.所能进行的计算也不同. https://blog.csdn.net/lucahan/article/details/51761610 对数据库操作更快更方便,如何证明?尤其是数据量比 ...

  6. freeRTOSConfig.h文件对FreeRTOS进行系统配置

    FreeRTOS内核是高度可定制的,使用配置文件FreeRTOSConfig.h进行定制.每个FreeRTOS应用都必须包含这个头文件,用户根据实际应用来裁剪定制FreeRTOS内核.这个配置文件是针 ...

  7. Shell 中字符串变量的赋值注意点

    1. 变量赋值 语法:var="saaaa" PS: 等号两边不能有空格 2. 脚本示例如下: #!/bin/sh # Get bug activity info # usage ...

  8. 连接SSH服务器的脚本,自动发送用户名和密码

    利用expect 自动输入用户名和密码 脚本如下 #!/usr/bin/expect # connect ssh server set timeout 30 spawn ssh -l user_nam ...

  9. WeexSDK之注册Components

    先来看一下注册Components的源码: + (void)_registerDefaultComponents { [self registerComponent:@"container& ...

  10. 第二十七节:Java基础面向对象-静态,单例模式,继承详情知识点

    前言 Java基础面向对象-静态,单例模式,继承详情知识点.静态-static关键字,static变量,静态代码块,代码块(不加静态),对象创建过程,单例模式,继承. 静态-static关键字 // ...