[Luogu 3613] 睡觉困难综合征
Description
给定一棵 \(n\) 个点的树,每个点上有位运算 \(opt\) 和一个权值 \(x\),位运算有 &,|,^ 三种。
要求支持:
- 修改点 \(v\) 的 \(opt\) 和 \(x_v\)
- 确定一个初始点权在 \([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] 睡觉困难综合征的更多相关文章
- 洛谷3613睡觉困难综合征(LCT维护链信息(前后缀)+贪心)
这个题目还是很好啊QWQ很有纪念意义 首先,如果在序列上且是单次询问的话,就是一个非常裸的贪心了QWQ这也是NOI当时原题的问题和数据范围 我们考虑上树的话,应该怎么做? 我的想法是,对于每一位建一个 ...
- Luogu 睡觉困难综合征 ([NOI2014]起床困难综合症)
一.[NOI2014]起床困难综合症 题目描述 网址:https://daniu.luogu.org/problemnew/show/2114 大意: 有一条链,链上每一个节点包含一个位运算f 与 一 ...
- 【刷题】洛谷 P3613 睡觉困难综合征
题目背景 刚立完Flag我就挂了WC和THUWC... 时间限制0.5s,空间限制128MB 因为Claris大佬帮助一周目由乃通过了Deus的题,所以一周目的由乃前往二周目世界找雪辉去了 由于二周目 ...
- 省队集训Day1 睡觉困难综合征
传送门:https://www.luogu.org/problem/show?pid=3613 [题解] 按二进制位分开,对于每一位,用“起床困难综合征”的方法贪心做. 写棵LCT,维护正反两种权值, ...
- Luogu3613 睡觉困难综合征/BZOJ4811 Ynoi2017 由乃的OJ 树链剖分、贪心
传送门 题意:给出一个$N$个点的树,树上每个点有一个位运算符号和一个数值.需要支持以下操作:修改一个点的位运算符号和数值,或者给出两个点$x,y$并给出一个上界$a$,可以选取一个$[0,a]$内的 ...
- 洛谷P3613 睡觉困难综合征(LCT,贪心)
洛谷题目传送门 膜拜神犇出题人管理员!!膜拜yler和ZSY!! 没错yler连续教我这个蒟蒻写起床困难综合症和睡觉困难综合症%%%Orz,所以按位贪心的思路可以继承下来 这里最好还是写树剖吧,不过我 ...
- 洛谷P3613 睡觉困难综合征(LCT)
题目: P3613 睡觉困难综合症 解题思路: LCT,主要是维护链上的多位贪心答案,推个公式:分类讨论入0/1的情况,合并就好了(公式是合并用的) 代码(我不知道之前那个为啥一直wa,改成结构体就好 ...
- Luogu3613 睡觉困难综合征
题面描述https://www.luogu.org/problemnew/show/3613 原题NOI2014起床困难综合症https://www.luogu.org/problemnew/show ...
- [bzoj3668][Noi2014]起床困难综合症/[洛谷3613]睡觉困难综合症
来自FallDream的博客,未经允许,请勿转载,谢谢. 21 世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳.作为一名青春阳光好少年,atm 一直坚持与起床困难综 ...
随机推荐
- PyCharm选择性忽略PEP8代码风格警告信息
用了几天的PyCharm,发现确实在编写Python代码上非常好用,但有一点体验不太好,就是代码编写时要按照PEP8代码风格编写,不然会有波浪线的警告信息.解决方法如下: 方法一: 将鼠标移到提示的地 ...
- tensorflow学习之(六)使用tensorboard展示神经网络的graph
# 创建神经网络, 使用tensorboard 展示graph import tensorflow as tf import numpy as np import matplotlib.pyplot ...
- delphi 中record 的类操作符重载简介
今天简单介绍一下 delphi 中record 的类操作符重载使用,就是如何 实现 record 之间的简单操作. 关于类操作符重载 ,大家可以看官方的文档. Delphi allows certai ...
- (22)Embrace the near win
https://www.ted.com/talks/sarah_lewis_embrace_the_near_win/transcript?referrer=playlist-talks_to_get ...
- shp文件和地理数据库文件的区别
存储文件结构不同.所能进行的计算也不同. https://blog.csdn.net/lucahan/article/details/51761610 对数据库操作更快更方便,如何证明?尤其是数据量比 ...
- freeRTOSConfig.h文件对FreeRTOS进行系统配置
FreeRTOS内核是高度可定制的,使用配置文件FreeRTOSConfig.h进行定制.每个FreeRTOS应用都必须包含这个头文件,用户根据实际应用来裁剪定制FreeRTOS内核.这个配置文件是针 ...
- Shell 中字符串变量的赋值注意点
1. 变量赋值 语法:var="saaaa" PS: 等号两边不能有空格 2. 脚本示例如下: #!/bin/sh # Get bug activity info # usage ...
- 连接SSH服务器的脚本,自动发送用户名和密码
利用expect 自动输入用户名和密码 脚本如下 #!/usr/bin/expect # connect ssh server set timeout 30 spawn ssh -l user_nam ...
- WeexSDK之注册Components
先来看一下注册Components的源码: + (void)_registerDefaultComponents { [self registerComponent:@"container& ...
- 第二十七节:Java基础面向对象-静态,单例模式,继承详情知识点
前言 Java基础面向对象-静态,单例模式,继承详情知识点.静态-static关键字,static变量,静态代码块,代码块(不加静态),对象创建过程,单例模式,继承. 静态-static关键字 // ...