Luogu3613 睡觉困难综合征
题面描述https://www.luogu.org/problemnew/show/3613
原题NOI2014起床困难综合症https://www.luogu.org/problemnew/show/2114做完原题就可以尝试解决这道题目了
题意:一棵n个节点的树,每个节点上有一个位运算操作符(与、或、异或)和一个数字,走过一个点的时候当前值就会和这个数字做相应运算。现在给定x,y,z,要求在[0,z]中选区一个初值使从x点走到y点的最终结果最大。支持动态修改点上的操作符与数字。
我太菜了完全不知道树链剖分去维护什么只知道LCT一顿乱搞。。。
咳咳,首先原题[起床困难综合症]得要切掉,然后你就知道这题的大致做法了了:记录初始以全0和全1走完后得到的答案,然后按位贪心即可(选高位一定比选低位优,就算低位全都可以选,因为这是二进制呀)。
为了方便起见,下文中所有的“答案”指以全0全1走完后得到的两个值,以0为下标表示是以全0开始的,1为下标表示是以全1开始的。
LCT维护啥?
LCT维护的东西是:在以这个点为根的splay中(我没有说这个点就是splay的根,是指以这个点为根的子树),从前往后经过每一个点的答案以及从后往前走经过每一个点的答案。
比如说,有一个叫做1号节点的点,在以她为根的splay中还有点2,3,其中2是她的左儿子,3是她的右儿子,那么在1号点上维护的东西就应该是:依次经过2-1-3的最终结果,以及依次经过3-1-2的最终结果。
那么两个结果怎么合并呢?
假如说我们有两段带合并的已经计算出答案的区间,分别对应f0,f1和g0,g1。我们设合并后的答案是h0,h1,那么有如下式子:
\]
\]
原因很简单,请自己YY~
需要注意的点:
以往的LCT维护的都是子树信息(废话,这题不也是),但同时也是无序的。这题维护的子树信息和左右子树的循序是有关系的,所以原来的翻转操作就需要略为修改。具体详见代码。
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll unsigned long long
const int N = 100005;
struct data
{
ll f0,f1;
data operator + (const data &b) const
{
data ans;
ans.f0=(~f0&b.f0)|(f0&b.f1);
ans.f1=(~f1&b.f0)|(f1&b.f1);
return ans;
}
}f[N],lo[N],ro[N];
int n,m,fa[N],ls[N],rs[N],rev[N],Stack[N],top;
ll gi()
{
ll x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
bool isroot(int x){return ls[fa[x]]!=x&&rs[fa[x]]!=x;}
void reverse(int x){swap(ls[x],rs[x]);swap(lo[x],ro[x]);rev[x]^=1;}
void pushdown(int x){if (rev[x]) reverse(ls[x]),reverse(rs[x]),rev[x]=0;}
void pushup(int x)
{
lo[x]=ro[x]=f[x];
if (ls[x]) lo[x]=lo[ls[x]]+lo[x],ro[x]=ro[x]+ro[ls[x]];
if (rs[x]) lo[x]=lo[x]+lo[rs[x]],ro[x]=ro[rs[x]]+ro[x];
}
void R_rotate(int x)
{
int y=fa[x],z=fa[y];
ls[y]=rs[x];
if (rs[x]) fa[rs[x]]=y;
fa[x]=z;
if (!isroot(y)) if (y==ls[z]) ls[z]=x;else rs[z]=x;
rs[x]=y;fa[y]=x;
pushup(y);
}
void L_rotate(int x)
{
int y=fa[x],z=fa[y];
rs[y]=ls[x];
if (ls[x]) fa[ls[x]]=y;
fa[x]=z;
if (!isroot(y)) if (y==ls[z]) ls[z]=x;else rs[z]=x;
ls[x]=y;fa[y]=x;
pushup(y);
}
void splay(int x)
{
Stack[top=1]=x;
for (int i=x;!isroot(i);i=fa[i])
Stack[++top]=fa[i];
while (top) pushdown(Stack[top--]);
while (!isroot(x))
{
int y=fa[x],z=fa[y];
if (isroot(y))
if (x==ls[y]) R_rotate(x);
else L_rotate(x);
else
if (y==ls[z])
if (x==ls[y]) R_rotate(y),R_rotate(x);
else L_rotate(x),R_rotate(x);
else
if (x==ls[y]) R_rotate(x),L_rotate(x);
else L_rotate(y),L_rotate(x);
}
pushup(x);
}
void access(int x){for (int y=0;x;y=x,x=fa[x]) splay(x),rs[x]=y,pushup(x);}
void makeroot(int x){access(x);splay(x);reverse(x);}
void split(int x,int y){makeroot(x);access(y);splay(y);}
void link(int x,int y){makeroot(x);fa[x]=y;}
int main()
{
n=gi();m=gi();gi();
for (int i=1;i<=n;i++)
{
int x=gi();ll y=gi();
if (x==1) f[i]=(data){0,y};
if (x==2) f[i]=(data){y,~0};
if (x==3) f[i]=(data){y,~y};
}
for (int i=1;i<n;i++)
{
int x=gi(),y=gi();
link(x,y);
}
while (m--)
{
int opt=gi(),x=gi(),y=gi();ll z=gi();
if (opt==1)
{
split(x,y);ll e=1,ans=0;
for (int k=63;k>=0;k--)
if (lo[y].f0&(e<<k))
ans+=e<<k;
else if (lo[y].f1&(e<<k)&&z>=(e<<k))
z-=e<<k,ans+=e<<k;
printf("%llu\n",ans);
}
if (opt==2)
{
makeroot(x);
if (y==1) f[x]=(data){0,z};
if (y==2) f[x]=(data){z,~0};
if (y==3) f[x]=(data){z,~z};
pushup(x);
}
}
return 0;
}
Luogu3613 睡觉困难综合征的更多相关文章
- Luogu3613 睡觉困难综合征/BZOJ4811 Ynoi2017 由乃的OJ 树链剖分、贪心
传送门 题意:给出一个$N$个点的树,树上每个点有一个位运算符号和一个数值.需要支持以下操作:修改一个点的位运算符号和数值,或者给出两个点$x,y$并给出一个上界$a$,可以选取一个$[0,a]$内的 ...
- Luogu 睡觉困难综合征 ([NOI2014]起床困难综合症)
一.[NOI2014]起床困难综合症 题目描述 网址:https://daniu.luogu.org/problemnew/show/2114 大意: 有一条链,链上每一个节点包含一个位运算f 与 一 ...
- 【刷题】洛谷 P3613 睡觉困难综合征
题目背景 刚立完Flag我就挂了WC和THUWC... 时间限制0.5s,空间限制128MB 因为Claris大佬帮助一周目由乃通过了Deus的题,所以一周目的由乃前往二周目世界找雪辉去了 由于二周目 ...
- 洛谷P3613 睡觉困难综合征(LCT,贪心)
洛谷题目传送门 膜拜神犇出题人管理员!!膜拜yler和ZSY!! 没错yler连续教我这个蒟蒻写起床困难综合症和睡觉困难综合症%%%Orz,所以按位贪心的思路可以继承下来 这里最好还是写树剖吧,不过我 ...
- 省队集训Day1 睡觉困难综合征
传送门:https://www.luogu.org/problem/show?pid=3613 [题解] 按二进制位分开,对于每一位,用“起床困难综合征”的方法贪心做. 写棵LCT,维护正反两种权值, ...
- 洛谷P3613 睡觉困难综合征(LCT)
题目: P3613 睡觉困难综合症 解题思路: LCT,主要是维护链上的多位贪心答案,推个公式:分类讨论入0/1的情况,合并就好了(公式是合并用的) 代码(我不知道之前那个为啥一直wa,改成结构体就好 ...
- P3613 睡觉困难综合征(LCT + 位运算)
题意 NOI2014 起床困难综合症 放在树上,加上单点修改与链上查询. 题解 类似于原题,我们只需要求出 \(0\) 和 \(2^{k - 1} - 1\) 走过这条链会变成什么值,就能确定每一位为 ...
- P3613 睡觉困难综合征(码力)
Luogu3613 实现细节较多,详见代码 #include<cstdio> #include<iostream> #include<cstring> #inclu ...
- [洛谷]P3613 睡觉困难综合征
题目大意:给出一棵n个点的树,每个点有一个运算符(与.或.异或)和一个数,支持两种操作,第一种修改一个点的运算符和数,第二种给出x,y,z,询问若有一个0~z之间的数从点x走到点y(简单路径),并且对 ...
随机推荐
- 洛谷P2286 [HNOI2004]宠物收养场【Treap】题解+AC代码
题目传送门啦~啦~啦~ 题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的 ...
- 在C#中几种常见数组复制方法的效率对比
原文是在http://blog.csdn.net/jiangzhanchang/article/details/9998229 看到的,本文在原文基础上增加了新的方法,并对多种数据类型做了更全面的对比 ...
- 加入GIMPS项目,寻找梅森素数!
截止到目前为止人类共找到了50个梅森素数,其中最后16个梅森素数都是通过GIMPS项目找到的. 为了激励人们寻找梅森素数和促进网格技术发展,总部设在美国旧金山的电子前沿基金会(EFF)于1999年3月 ...
- php 高并发下 秒杀处理思路
1.用额外的单进程处理一个队列,下单请求放到队列里,一个个处理,就不会有并发的问题了,但是要额外的后台进程以及延迟问题,不予考虑. 2.数据库乐观锁,大致的意思是先查询库存,然后立马将库存+1,然后订 ...
- MySQL Server 5.0安装教程
相信很多朋友刚开始接触mysql数据库服务器,下面是mysql的安装教程,步骤明细也有详细的说明. 工具/原料 mysql MySQL安装的图解 1 打开下载的mysql安装文件mysql-5 ...
- Mysql主从复制_模式之日志点复制
MySQL数据复制的原理 MySQL复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新.删除等等).因此,要进行复制,必须在主服务器上启用二进制日志. 每个从服务器从主服务器接收主服务器已经记 ...
- Google 浏览器被劫持怎么办?
chrome://version/ 输入以上语句,在命令行中可看到恶意网址,复制该命令行,修改后面的网址即可
- DAVINCI DM6446 开发攻略——V4L2视频驱动和应用分析
针对DAVINCI DM6446平台,网络上也有很多网友写了V4L2的驱动,但只是解析Montavista linux-2.6.10 V4L2的原理.结构和函数,深度不够.本文决定把Montavis ...
- 一句python,一句R︱python中的字符串操作、中文乱码
先学了R,最近刚刚上手python,所以想着将python和R结合起来互相对比来更好理解python.最好就是一句python,对应写一句R. pandas可谓如雷贯耳,数据处理神器. 以下符号: = ...
- 图像处理------透明混合 - Alpha Blending效果
基本原理: 图像的透明混合有个专属名词– Alpha Blending 对任意两张图像可以合成为一张图像,合成图像的像素取值根据数学公式: RGB3 = (1- a) * RGB1 + a * RGB ...