Luogu 睡觉困难综合征 ([NOI2014]起床困难综合症)
一.[NOI2014]起床困难综合症
题目描述
网址:https://daniu.luogu.org/problemnew/show/2114
大意:
有一条链,链上每一个节点包含一个位运算f 与 一个值w , 一个值V从链首出发。
每经过一个点u ,有: \(V = V (f)w\),其中f = {&、|、^}中的一个。
现在限定初始值V在区间\([0,R]\)中,请选定一个值,使得最终结果最大。
题目解法
史上最简单的NOI题目,当时肯定一群大佬秒A。
显然对于二进制,每一位的运算之间没有影响。
所以对于每一位,假设其为0或1,但进去暴力跑一遍的到结果res[0]与res[1]。
最后从高位向低位贪心,此位只要不超过R的限制就选择res=1的数字即可。
实现代码
不存在的
二、LuoguP3613 睡觉困难综合征
题目描述
网址:https://daniu.luogu.org/problemnew/show/3613
大意:
类似与上面那道题,树上的每一个节点有一个位运算符与一个权值。
那么现在这颗树会有两种操作:
- [1] 修改\(x,y,z\):把x节点运算符修改为y,权值为z
- [2] 查询\(x,y,z\): 查询把x到y这条路径作为上题中的链,初值V属于\([0,z]\)时的最大结果。
对于每一个询问操作,选择一个初值V,使其通过路径后的值最大。
(节点数,操作数)<=100000,时限0.5 sec。
题目解法
Luogu 的大牛们一改,这题就变的相当有难度了。
现在路径在不断变化,链也不断在变化,不可能向之前那样暴力走一遍路径了。
显然需要分离路径要用到\(LCT\)。 \(LCT\)维护什么呢?
正确的做法是维护正向与反向两条道路每一位都为0的结果与每一位都为1的结果。
例如一个节点x的左右儿子分别为a、b,那么就要维护a->x->b与b->x->a两条路径。
这样才能保证LCT反转时结果正确。
我们记\(oder[i]\)表示正向的移动结果,\(dder[i]\)为反向的移动结果。
那么每一个点,我们维护四个东西:\(oder[i][0]\),\(oder[i][1]\),\(dder[i][0]\),\(dder[i][1]\)。
考虑一下如何转移,以正向结果的转移为例。
假设我们已经的得到了f0,f1与g0,g1, 现在合并。那么转移为:
\[h0 = ( No(f0) And (g0))Or((f0) And (g1))\]
\[h1 = ( No(f1) And (g0))Or((f1) And (g1))\]
写得正常点就是 h0 = (~f0 & g0) | ( f0 & g1) ; h1 = (~f1 & g0) | (f1 & g1)
即本次走了结果为0则第二次走的为0。结果为1的类似。
查询也类似上面那题。
这里注意此题中Makeroot时一定要先转再打标记,防止查询时对应点还没有旋转。
实现代码
#include<bits/stdc++.h>
#define ll unsigned long long
#define RG register
#define IL inline
#define maxn 100100
#define lr oder
#define rl dder
#define Read() gi()
using namespace std;
ll fa[maxn],rev[maxn],ch[maxn][2],stk[maxn]; ll N,M,K,ze;
struct Value{ll f0,f1;}oder[maxn],dder[maxn],val[maxn],G;
IL ll gi(){
RG ll date = 0, m = 1; RG char ch = 0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch = getchar();
if(ch == '-'){m = -1; ch = getchar();}
while(ch>='0' && ch<='9')
{date=date*10+ch-'0'; ch = getchar();}
return date*m;
}
IL void Reverse(RG ll x){
swap(ch[x][0],ch[x][1]);
swap(oder[x],dder[x]); rev[x]^=1;
}
IL void PushDown(RG ll x){
if(!rev[x])return;
Reverse(ch[x][0]); Reverse(ch[x][1]);
rev[x] = 0; return;
}
IL Value Merge(RG Value F,RG Value S){
G.f0 = (~F.f0 & S.f0) | (F.f0 & S.f1);
G.f1 = (~F.f1 & S.f0) | (F.f1 & S.f1);
return G;
}
IL void PushUp(RG ll x){
oder[x] = dder[x] = val[x];
if(ch[x][0])oder[x] = Merge(oder[ch[x][0]],oder[x]);
if(ch[x][0])dder[x] = Merge(dder[x],dder[ch[x][0]]);
if(ch[x][1])oder[x] = Merge(oder[x],oder[ch[x][1]]);
if(ch[x][1])dder[x] = Merge(dder[ch[x][1]],dder[x]);
}
IL bool Son(RG ll x){return ch[fa[x]][1] == x; }
IL bool Isroot(RG ll x){return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x; }
IL void Rot(RG ll x){
RG int y = fa[x],z = fa[y],c = Son(x);
if(!Isroot(y))ch[z][Son(y)] = x; fa[x] = z;
ch[y][c] = ch[x][!c]; fa[ch[y][c]] = y;
ch[x][!c] = y; fa[y] = x; PushUp(y);
}
IL void Splay(RG ll x){
RG ll top = 0; stk[++top] = x;
for(RG ll i = x; !Isroot(i); i = fa[i])stk[++top] = fa[i];
while(top)PushDown(stk[top--]);
for(RG ll y = fa[x]; !Isroot(x); Rot(x),y = fa[x])
if(!Isroot(y))Son(x) ^ Son(y) ? Rot(x) : Rot(y);
PushUp(x);
}
IL void Access(RG ll x){ for(RG ll y = 0; x; y=x,x=fa[x])Splay(x),ch[x][1]=y,PushUp(x); }
IL void Makeroot(RG ll x){Access(x); Splay(x); Reverse(x); }
IL void Link(RG ll x,RG ll y){ Makeroot(x); fa[x]=y; }
IL void Split(RG ll x,RG ll y){ Makeroot(x); Access(y); Splay(y); }
IL ll Query(RG ll x,RG ll y,RG ll z){
Split(x,y); RG ll ans = 0,u = 1,num = 0;
for(RG int i = 63; i >=0; i --){
if(oder[y].f0&(u<<i)){ans |= (u<<i);continue;}
else if((oder[y].f1&(u<<i)))
{ if(num|(u<<i))<=z){ans |= (u<<i); num|=(u<<i);} }
}return ans;
}
IL void Update(RG ll x,RG ll y,RG ll z){
Makeroot(x);
if(y == 1)val[x] = (Value){ze,z};
if(y == 2)val[x] = (Value){z,~ze};
if(y == 3)val[x] = (Value){z,~z};
PushUp(x);
}
int main()
{
N = gi(); M = gi(); K = gi();
RG ll t = 1; ze = 0;
for(RG ll i = 1; i <= N; i ++){
RG ll kd = gi(),dt = gi();
if(kd == 1)val[i] = (Value){ze,dt};
if(kd == 2)val[i] = (Value){dt,~ze};
if(kd == 3)val[i] = (Value){dt,~dt};
}
for(RG ll i = 1; i <= N-1; i ++){
RG ll xx = gi(),yy = gi();
Link(xx,yy);
}
while(M--)
{
RG ll op = gi(),x = gi(),y = gi(),z = gi();
if(op == 1)printf("%llu\n",Query(x,y,z));
if(op == 2)Update(x,y,z);
}return 0;
}
Luogu 睡觉困难综合征 ([NOI2014]起床困难综合症)的更多相关文章
- [P2114] [NOI2014]起床困难综合症 (位运算)
题面 传送门:https://www.luogu.org/problemnew/show/P2114 Solution 一道很有意思的位运算题. 要做这一题,我们首先得了解一个很重要的特点 位运算过程 ...
- bzoj3668: [Noi2014]起床困难综合症
从高位到低位枚举期望的应该是ans最高位尽量取一.如果该数最高位为o的话能够取得1直接更新ans否则判断该位取1是否会爆m不会的话就加上. #include<cstdio> #includ ...
- NOI2014 起床困难综合症
3668: [Noi2014]起床困难综合症 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 225 Solved: 153[Submit][Stat ...
- BZOJ 3668: [Noi2014]起床困难综合症( 贪心 )
之前以为xor,or,and满足结合律...然后连样例都过不了 早上上体育课的时候突然想出来了...直接处理每一位是1,0的最后结果, 然后从高位到低位贪心就可以了... 滚去吃饭了.. ------ ...
- BZOJ 3668: [Noi2014]起床困难综合症【贪心】
3668: [Noi2014]起床困难综合症 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1305[Submit][St ...
- P2114 [NOI2014]起床困难综合症(二进制)
P2114 [NOI2014]起床困难综合症 我们开始设俩数,一个二进制表示全是1,另一个全是0(就是2147483647 和 0 辣) 蓝后跑一遍门 于是最后有4种情况 1->0,1-> ...
- 洛谷P2114 [NOI2014]起床困难综合症
P2114 [NOI2014]起床困难综合症 题目描述 21世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳.作为一名青春阳光好少年,atm一直坚持与起床困难综合症作 ...
- bzoj千题计划238:bzoj3668: [Noi2014]起床困难综合症
http://www.lydsy.com/JudgeOnline/problem.php?id=3668 这..一位一位的来就好了呀 #include<cstdio> #include&l ...
- [NOI2014]起床困难综合症(二进制+贪心)
题目 [NOI2014]起床困难综合症 做法 先用全\(0\)和全\(1\)去运行一下,再在满足\(m\)的限制下,贪心地从高位到低位选择即可
随机推荐
- 用Android属性动画实现和演示迪士尼动画基本原则
本文将介绍在Android平台上实现和演示迪士尼动画基本准则. 项目开源,GitHub: https://github.com/vhow/animation 说明: 演示动画原则的想法源自 Anima ...
- [CJOJ2410]数列操作d
[CJOJ2410]数列操作d 标签: 线段树 题解 没时间写题了,我来嘴巴AC吧. 注意区间加的这个值不是 确定的,随着元素位置的变化而改变. 只需要能维护这个东西剩下的就很好做了. 那么\(x*( ...
- 02 Java类的加载机制
1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...
- java5 - 数组与排序算法
数组是什么? 一.一维数组 1 声明与定义的区别 一般的情况下我们常常这样叙述, 把建立空间的声明称之为"定义", 而把不需要建立存储空间称之为"声明". 很明 ...
- yii pageTitle与Yii::app()->name的区别
我们会在main中修改: 'name'=>'傻逼管理系统', 在视图页中:Yii::app()->name时,会输出 傻逼管理系统:可是当我们用$this->pageTitle时 ...
- Yii的URL助手
Url 帮助类 获得通用 URL 记住 URLs 检查相对 URLs Url 帮助类提供一系列的静态方法来帮助管理 URL. 获得通用 URL 有两种获取通用 URLS 的方法 :当前请求的 home ...
- 在ASP.Net Core下,Autofac实现自动注入
之前使用以来注入的时候,都是在xml配置对应的接口和实现类,经常会出现忘了写配置,导致注入不生效,会报错,而且项目中使用的是SPA的模式,ajax报错也不容易看出问题,经常会去排查日志找问题. 于是在 ...
- Egret学习笔记 (Egret打飞机-2.开始游戏)
打开 Egret Wing,新建一个Egret游戏项目,然后删掉默认生成的createGameScene方法里面的东西 然后新建一个BeginScene.ts的文件,作为我们的游戏的第一个场景 cla ...
- C#中ASCII码学习心得
1.利用调用ASCIIEncoding类来实现各种转换.如简单个ACS码和int转换. ***利用(int)ASCIIEncoding类对象.GetBytes(character)[0]得到整数: p ...
- U-Boot启动过程
开发板上电后,执行U-Boot的第一条指令,然后顺序执行U-Boot启动函数.看一下board/smdk2410/u-boot.lds这个链接脚本,可以知道目标程序的各部分链接顺序.第一个要链接的是c ...