这个题目还是很好啊QWQ很有纪念意义

首先,如果在序列上且是单次询问的话,就是一个非常裸的贪心了QWQ这也是NOI当时原题的问题和数据范围

我们考虑上树的话,应该怎么做?

我的想法是,对于每一位建一个LCT来做,然后对一个点x维护,当前是0到链顶的结果,当前是1到顶的结果,当前是0到底的结果,当前是1到底的结果(之所以维护后两个是因为\(reverse\)操作的存在)

这样的话,对于每次询问,我就可以直接\(split\),然后贪心的询问。

不过很可惜,这个算法的复杂度是\(O(qklogn)\)的

并不能跑过(虽然没试过硬卡常行不行)

那么应该怎么做呢QWQ 这时候,我选择了看题解。

首先,经过仔细思考,我们会发现,QWQ对于题目来说,其实并不需要按位来做,可以直接维护\(f_0,f_1,g_0,g_1\)四个值,分别表示所有位0到链顶的结果,所有二进制位全是1的数到顶的结果,所有位全是0到底的结果,所有位全是1到底的结果

那么这个东西应该怎么转移呢?

这里合并的大概思想是 全0走到中间节点之后,是0的那几位,相当于后面的全0走的,是1的那几位,相当于是后面全1走的 ,全1的也是同理

而之所以这么写,是因为运用了与的美妙的性质,只有两边都是1,最终结果才是1。

所以,假设对于当前是全零0来说,考虑前一半,是计算0的那几位,要是采用了&与这个运算,如果最后走完,\(f_0\)的某一位是0,那么最一开始无论是什么,最终&完都是0,也就不会存在一开始是1的那些位影响答案。

要是这一位是1,我们要满足与完 是1的话,同时去除一开始是1的位的贡献,我们就需要先取反,然后再&

其他的其实也是同理

Node merge(Node a,Node b) //我们默认a在前,b在后
{
Node c;
c.f0=(~a.f0 & b.f0) + (a.f0 & b.f1); //这里合并的大概思想是 全0走到中间节点之后,是0的那几位,相当于后面的全0走的,是1的那几位,相当于是后面全1走的
c.f1=(~a.f1 & b.f0) + (a.f1 & b.f1); //而之所以这么写,是因为运用了与的美妙的性质,只有两边都是1,最终结果才是1。所以,假设对于当前是0来说,只有后面全零弄出来是1,我们当前的的答案才是1,那么为了出来1,我们就需要先取反,然后再&
return c;
} void update(unsigned long long x)
{
zheng[x]=fan[x]=val[x];
if (ch[x][0])
{
zheng[x]=merge(zheng[x],zheng[ch[x][0]]);
fan[x]=merge(fan[ch[x][0]],fan[x]);
}
if (ch[x][1])
{
zheng[x]=merge(zheng[ch[x][1]],zheng[x]);
fan[x]=merge(fan[x],fan[ch[x][1]]);
}
}

其他的LCT操作的话,也就和别的没什么区别了。

这里再讲一下底下那个贪心的过程

unsigned long long ans=ling;
split(x,y);
//cout<<1<<endl;
for (long long i=k-1;i>=0;i--)
{
if (fan[y].f0&power[i])
{
ans=ans+power[i];
continue;
}
if (fan[y].f1 & power[i])
{
if (power[i]>z) continue;
ans=ans+power[i];
z-=power[i];
}
//cout<<i<<endl;
}
cout<<ans<<"\n";

从高位向低位考虑,如果当前位填0,最终结果是1的话,那么就填0。

如果当前位填1,最终结果才能是1。我们就需要比较一下剩余的值是否比这个位填1的数大,大的话才能填

以此类推

QWQ

记得开\(unsigned\ long\ long\)

上代码

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk makr_pair
#define ll long long
#define lc ch[x][0]
#define rc ch[x][1] using namespace std; inline unsigned long long read()
{
unsigned long long x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
} const int maxn = 1e6+1e2; struct Node{
unsigned long long f0,f1;
};
unsigned long long ch[maxn][3];
unsigned long long rev[maxn],fa[maxn];
Node zheng[maxn],fan[maxn];
unsigned long long n,m;
Node val[maxn];
unsigned long long ling =0; unsigned long long son(unsigned long long x)
{
if (ch[fa[x]][0]==x) return 0;
else return 1;
} bool notroot(unsigned long long x)
{
return ch[fa[x]][0]==x || ch[fa[x]][1]==x;
} void reverse(unsigned long long x)
{
swap(ch[x][0],ch[x][1]);
swap(zheng[x].f0,fan[x].f0);
swap(zheng[x].f1,fan[x].f1);
rev[x]^=1;
} Node merge(Node a,Node b) //我们默认a在前,b在后
{
Node c;
c.f0=(~a.f0 & b.f0) + (a.f0 & b.f1); //这里合并的大概思想是 全0走到中间节点之后,是0的那几位,相当于后面的全0走的,是1的那几位,相当于是后面全1走的
c.f1=(~a.f1 & b.f0) + (a.f1 & b.f1); //而之所以这么写,是因为运用了与的美妙的性质,只有两边都是1,最终结果才是1。所以,假设对于当前是0来说,只有后面全零弄出来是1,我们当前的的答案才是1,那么为了出来1,我们就需要先取反,然后再&
return c;
} void update(unsigned long long x)
{
zheng[x]=fan[x]=val[x];
if (ch[x][0])
{
zheng[x]=merge(zheng[x],zheng[ch[x][0]]);
fan[x]=merge(fan[ch[x][0]],fan[x]);
}
if (ch[x][1])
{
zheng[x]=merge(zheng[ch[x][1]],zheng[x]);
fan[x]=merge(fan[x],fan[ch[x][1]]);
}
} void pushdown(unsigned long long x)
{
if (rev[x])
{
if (ch[x][1]) reverse(ch[x][1]);
if (ch[x][0]) reverse(ch[x][0]);
rev[x]=0;
}
} void rotate(unsigned long long x)
{
unsigned long long y=fa[x],z=fa[y];
unsigned long long b=son(x),c=son(y);
if (notroot(y)) ch[z][c]=x;
fa[x]=z;
ch[y][b]=ch[x][!b];
fa[ch[x][!b]]=y;
ch[x][!b]=y;
fa[y]=x;
update(y);
update(x);
} unsigned long long st[maxn]; void splay(unsigned long long x)
{
unsigned long long y=x,cnt=0;
st[++cnt]=y;
while (notroot(y)) y=fa[y],st[++cnt]=y;
while (cnt) pushdown(st[cnt--]);
while (notroot(x))
{
unsigned long long y=fa[x],z=fa[y];
unsigned long long b=son(x),c=son(y);
if (notroot(y))
{
if (b==c) rotate(y);
else rotate(x);
}
rotate(x);
}
update(x);
} void access(unsigned long long x)
{
for (unsigned long long y=0;x;y=x,x=fa[x])
{
splay(x);
ch[x][1]=y;
update(x);
}
} void makeroot(unsigned long long x)
{
access(x);
splay(x);
reverse(x);
} unsigned long long findroot(unsigned long long x)
{
access(x);
splay(x);
while (ch[x][0])
{
pushdown(x);
x=ch[x][0];
}
return x;
} void split(unsigned long long x,unsigned long long y)
{
makeroot(x);
access(y);
splay(y);
} void link(unsigned long long x,unsigned long long y)
{
makeroot(x);
if(findroot(y)!=x) fa[x]=y;
} unsigned long long power[maxn]; unsigned long long ymh = 2;
unsigned long long k; signed main()
{
n=read(),m=read(),k=read();
power[0]=1;
for (unsigned long long i=1;i<64;i++) power[i]=power[i-1]*ymh; for (unsigned long long i=1;i<=n;i++)
{
unsigned long long y=read(),x=read();
if (y==1)
{
val[i]=(Node){ling,x};
}
if (y==2)
{
val[i]=(Node){x,~ling};
}
if (y==3)
{
val[i]=(Node){x,~x};
}
}
for (unsigned long long i=1;i<n;i++)
{
unsigned long long x=read(),y=read();
link(x,y);
} //cout<<1<<endl;
for (unsigned long long i=1;i<=m;i++)
{
unsigned long long opt=read(),x=read(),y=read(),z=read();
if (opt==2)
{
splay(x);
if (y==1) val[x]=(Node){ling,z};
if (y==2) val[x]=(Node){z,~ling};
if (y==3) val[x]=(Node){z,~z};
}
if (opt==1)
{
unsigned long long ans=ling;
split(x,y);
//cout<<1<<endl;
for (long long i=k-1;i>=0;i--)
{
if (fan[y].f0&power[i])
{
ans=ans+power[i];
continue;
}
if (fan[y].f1 & power[i])
{
if (power[i]>z) continue;
ans=ans+power[i];
z-=power[i];
}
//cout<<i<<endl;
}
cout<<ans<<"\n";
}
}
return 0;
}

洛谷3613睡觉困难综合征(LCT维护链信息(前后缀)+贪心)的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 洛谷P3613 睡觉困难综合征

    传送门 题解 人生第一道由乃…… 做这题之前应该先去把这一题给切掉->这里 我的题解->这里 然后先膜一波zsy大佬和flashhu大佬 大体思路就是先吧全0和全1的都跑答案,然后按位贪心 ...

  7. [Luogu 3613] 睡觉困难综合征

    Description 给定一棵 \(n\) 个点的树,每个点上有位运算 \(opt\) 和一个权值 \(x\),位运算有 &,|,^ 三种. 要求支持: 修改点 \(v\) 的 \(opt\ ...

  8. P3613 睡觉困难综合征 LCT+贪心+位运算

    \(\color{#0066ff}{ 题目描述 }\) 由乃这个问题越想越迷糊,已经达到了废寝忘食的地步.结果她发现--晚上睡不着了!只能把自己的一个神经元(我们可以抽象成一个树形结构)拿出来,交给D ...

  9. 洛谷P2114起床困难综合征

    从高位到低位按位枚举,贪心.如果该位填1比填0结果优且填1不会超出m限制,那就填1,否则填0 /*by SilverN*/ #include<iostream> #include<c ...

随机推荐

  1. python常用工具库介绍

    Numpy:科学计算 HOME:  http://www.numpy.org/ NumPy is the fundamental package for scientific computing wi ...

  2. 怎样去除EXCEL中的重复行

    工具/原料 安装了EXCEL2010的电脑一台 步骤/方法   假如我们的表格中有下图所示的一系列数据,可以看出其中有一些重复.   首先我们选中所有数据.可以先用鼠标点击"A1单元格&qu ...

  3. golang context包

    go context标准库 context包在Go1.7版本时加入到标准库中.其设计目标是给Golang提供一个标准接口来给其他任务发送取消信号和传递数据.其具体作用为: 可以通过context发送取 ...

  4. Appium问题解决方案(9)- Original error: Failed to launch Appium Settings app: Condition unmet after 5090 ms

    背景 执行代码报错 解决方法 该问题并不常见,主要是手机操作系统的问题 程序无法无法自动打开appiumsettings,那么我们可以手动打开appiumsettings服务(程序没有界面,会出现打开 ...

  5. 第三课:GDB 常用的调试命令概览

    先给出一个常用命令的列表,后面会结合具体的例子详细介绍每个命令的用法. 命令名称 命令缩写 命令说明 run r 运行一个程序 continue c 让暂停的程序继续运行 next n 运行到下一行 ...

  6. 查询同一张表符合条件的某些数据的id拼接成一个字段返回

    同一张表存在类似多级菜单的上下级关系的数据,查询出符合条件的某些数据的id拼接成一个字段返回: SELECT CONCAT(a.pid, ',', b.subid) AS studentIDS FRO ...

  7. MySQL日志管理、备份、恢复

    目录: 一.MySQL 日志管理 二.数据库备份的重要性与分类 三.常见的备份方法 四.MySQL完全备份 五.数据库完全备份分类 六.MySQL增量备份 七.MySQL数据库增量恢复 八.MySQL ...

  8. 双非Java的学习之旅以及秋招路程

    个人信息: 趁着中秋写个帖子记录一下吧.渣渣本,无实习,无高质量证书,走了很多弯路,最后选择的Java后端.现在算是半躺平了,接了几个中小厂的offer保底,20w多的薪资,后面还有几家公司接着面.不 ...

  9. select后给字段起别名,where和group后不能用,但having后可以

    为什么mysql having的条件表达式可以直接使用select后的别名? SQL语句的语法顺序: FROM -> WHERE -> GROUP BY -> HAVING -> ...

  10. 通过Wireshark抓包分析谈谈DNS域名解析的那些事儿

    文/朱季谦 本文主要想通过动手实际分析一下是如何通过DNS服务器来解析域名获取对应IP地址的,毕竟,纸上得来终觉浅,绝知此事要躬行. 域名与IP地址 当在浏览器上敲下"www.baidu.c ...