题意

NOI2014 起床困难综合症 放在树上,加上单点修改与链上查询。

题解

类似于原题,我们只需要求出 \(0\) 和 \(2^{k - 1} - 1\) 走过这条链会变成什么值,就能确定每一位为 \(0 / 1\) 走完后变成什么值。

我们对于 \(LCT\) 每个节点维护两个值 \(r_0,r_1\) 表示 \(0\) 和 \(2 ^ k - 1\) 从当前 \(LCT\) 维护的链底走到这个点会变成什么值。

然后我们就可以把位运算操作变成一个值放在这个点上。

合并信息的时候,可以这样写:

inline Data operator + (const Data &lhs, const Data &rhs) {return (Data) {(~lhs.r0 & rhs.r0) | (lhs.r0 & rhs.r1),(~lhs.r1 & rhs.r0) | (rhs.r1 & lhs.r1)};
}

此处 \(\sim\) 是取反,也就是所有位反转,注意此处需要用 unsigned long long 存,就没有符号位,不会进行反转。

解释前面那个地方 (~lhs.r0 & rhs.r0) 意味着最开始从 \(0\) 开始走,走完左子树后还是 \(0\) 然后继续走 得到的结果,

(lhs.r0 & rhs.r1) 就是一开始从 \(0\) 走,走完左子树后变成 \(1\) 然后继续走 得到的结果。

另外一个也是同理了,只是最开始从 \(1\) 走。

但是这样还是不够的,因为位运算是有顺序的,\(reverse\) 的时候答案就会错误,所以我们多存一个逆向的值就行了。

最后只需要像原题按位贪心就行了。

复杂度是 \(O(n + q (\log n + k))\) 的。

总结

位运算时需要对所有位进行翻转可以用 \(\sim\) ,十分方便。

\(LCT\) 维护信息如果有顺序的话,那么需要维护一个逆向操作的答案才行。

代码

具体可以看看代码实现(虽然写的有点长。。)

#include <bits/stdc++.h>#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define pb push_backusing namespace std;typedef unsigned long long ull;template<typename T> inline bool chkmin(T &a, T b) {return b < a ? a = b, 1 : 0;}
template<typename T> inline bool chkmax(T &a, T b) {return b > a ? a = b, 1 : 0;}namespace pb_ds
{   namespace io{const int MaxBuff = 1 << 22;const int Output = 1 << 24;char B[MaxBuff], *S = B, *T = B;
#define getc() ((S == T) && (T = (S = B) + fread(B, 1, MaxBuff, stdin), S == T) ? 0 : *S++)char Out[Output], *iter = Out;inline void flush(){fwrite(Out, 1, iter - Out, stdout);iter = Out;}}template<class Type> inline Type read(){using namespace io;register char ch; register Type ans = 0; register bool neg = 0;while(ch = getc(), (ch < '0' || ch > '9') && ch != '-')     ;ch == '-' ? neg = 1 : ans = ch - '0';while(ch = getc(), '0' <= ch && ch <= '9') ans = ans * 10 + ch - '0';return neg ? -ans : ans;}template<class Type> inline void Print(register Type x, register char ch = '\n'){using namespace io;if(!x) *iter++ = '0';else{if(x < 0) *iter++ = '-', x = -x;static int s[100]; register int t = 0;while(x) s[++t] = x % 10, x /= 10;while(t) *iter++ = '0' + s[t--];}*iter++ = ch;}}using namespace pb_ds;void File() {
#ifdef zjp_shadowfreopen ("P3613.in", "r", stdin);freopen ("P3613.out", "w", stdout);
#endif
}const int N = 1e5 + 1e3;#define ls(o) ch[o][0]
#define rs(o) ch[o][1]struct Data {ull r0, r1;
};inline Data operator + (const Data &lhs, const Data &rhs) {return (Data) {(~lhs.r0 & rhs.r0) | (lhs.r0 & rhs.r1),(~lhs.r1 & rhs.r0) | (rhs.r1 & lhs.r1)};
}template<int Maxn>
struct Link_Cut_Tree {int ch[Maxn][2], fa[Maxn];Data fo[Maxn], fr[Maxn], val[Maxn];inline bool is_root(int o) {return ls(fa[o]) != o && rs(fa[o]) != o;}inline bool get(int o) {return rs(fa[o]) == o;}inline void push_up(int o) {fo[o] = fr[o] = val[o];if (ls(o)) fo[o] = fo[ls(o)] + fo[o], fr[o] = fr[o] + fr[ls(o)];if (rs(o)) fo[o] = fo[o] + fo[rs(o)], fr[o] = fr[rs(o)] + fr[o];}inline void rotate(int v) {int u = fa[v], t = fa[u], d = get(v);fa[ch[u][d] = ch[v][d ^ 1]] = u;fa[v] = t; if (!is_root(u)) ch[t][rs(t) == u] = v;fa[ch[v][d ^ 1] = u] = v;push_up(v); push_up(u);}bool rev[Maxn];inline void Get_Rev(int o) {rev[o] ^= 1; swap(ls(o), rs(o));swap(fo[o], fr[o]);}inline void push_down(int o) {if (rev[o])Get_Rev(ls(o)), Get_Rev(rs(o)), rev[o] = false;}void Push_All(int o) {if (!is_root(o)) Push_All(fa[o]); push_down(o);}inline void Splay(int o) {Push_All(o);for (; !is_root(o); rotate(o))if (!is_root(fa[o])) rotate(get(o) != get(fa[o]) ? o : fa[o]);push_up(o);}inline void Access(int o) {for (int t = 0; o; o = fa[t = o])Splay(o), rs(o) = t, push_up(o);}inline void Make_Root(int o) {Access(o); Splay(o); Get_Rev(o);}inline void Split(int u, int v) {Make_Root(u); Access(v); Splay(v);}};Link_Cut_Tree<N> T;vector<int> G[N];
void Build(int u = 1, int fa = 0) {T.fa[u] = fa; for (int v : G[u]) if (v != fa) Build(v, u);
}int main () {File();int n = read<int>(), m = read<int>(), k = read<int>();For (i, 1, n) {int x = i, y = read<int>(); ull z = read<ull>();if (y == 1) T.val[x].r0 = 0ull, T.val[x].r1 = z;if (y == 2) T.val[x].r0 = z, T.val[x].r1 = ~0ull;if (y == 3) T.val[x].r0 = z, T.val[x].r1 = ~z;T.push_up(x);}For (i, 1, n - 1) { int u = read<int>(), v = read<int>(); G[u].pb(v); G[v].pb(u); } Build();For (i, 1, m) {int opt = read<int>(), x = read<int>(), y = read<int>(); ull z = read<ull>();if (opt == 1) {T.Split(x, y);ull val0 = T.fo[y].r0, val1 = T.fo[y].r1, res = 0, cur = 0;for (ull i = 1ull << (k - 1); i; i >>= 1) {if ((val0 & i) < (val1 & i) && cur + i <= z)cur += i, res += val1 & i;else res += val0 & i;}Print(res);} else {T.Access(x); T.Splay(x);if (y == 1) T.val[x].r0 = 0ull, T.val[x].r1 = z;if (y == 2) T.val[x].r0 = z, T.val[x].r1 = ~0ull;if (y == 3) T.val[x].r0 = z, T.val[x].r1 = ~z;T.push_up(x);}}io :: flush();return 0;}

转载于:https://www.cnblogs.com/zjp-shadow/p/9733086.html

P3613 睡觉困难综合征(LCT + 位运算)相关推荐

  1. [Luogu P3613] 睡觉困难综合征

    洛谷传送门 题目描述 因为Claris大佬帮助一周目由乃通过了Deus的题,所以一周目的由乃前往二周目世界找雪辉去了 由于二周目世界被破坏殆尽,所以由乃和雪辉天天都忙着重建世界(其实和MC差不多吧), ...

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

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

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

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

  4. CH0104 起床困难综合症(位运算典例)

    传送门:起床困难综合症 思路:要知道位运算永远只会改变本位,与其它位泾渭分明.据此,我们不难看出,每个位仅有1.0两种状态,在全部运算后,寻找两种状态的最大结果即可. #include<cstr ...

  5. 起床困难综合症(位运算)

    题目链接 AcWing 998. 题意:最初攻击力不知道,给定m次位运算操作,计算经过m次位运算操作后的最大值. 思路:在代码顶部 混合位运算不具有分配律,交换律,结合律 // 存在多个不同的位运算符 ...

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

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

  7. P2114-[NOI2014]起床困难综合症【位运算】

    正题 题目大意 若干个位操作,求一个值xxx使得进行了以后的最大值. 解题思路 每位分开运算计算出每一位为0和为1时的结果,然后贪心选择. codecodecode // luogu-judger-e ...

  8. Luogu2114 [NOI2014]起床困难综合症 【位运算】

    题目分析: 按位处理即可 代码: 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 105000; ...

  9. 起床困难综合症(位运算

    题目 结果的第k位只与初值的第k位有关 #include<bits/stdc++.h> using namespace std; #define int long long const i ...

最新文章

  1. Python-字符串操作方法 [转]
  2. 从Windows Server 2003升级到2008
  3. python发明者叫什么-Guido发明的python语言是哪一年正式发布的?
  4. mysql的dockerfile_Dockerfile构建MySQL
  5. 前端框架MVC/MVVM分析系列
  6. CTO要我把这份MySQL规范贴在工位上!
  7. zabbix简单介绍(1)
  8. 利用vector实现一对一(pair<int,int>)
  9. 2020 年 Go 语言盘点:Go 的前进步伐不可阻挡
  10. Redis缓存穿透、缓存雪崩和缓存击穿理解
  11. python时间模块倒计时_Python时间模块
  12. [DB] oracle删除重复数据
  13. 【AAAI2021】自动跨主题作文属性评分
  14. 震精 - PostgreSQL 递归查询 - 树型数据按路径分组输出
  15. MSM8926处理器
  16. Mysql和ES数据同步方案汇总
  17. python-文字pdf转换为图片pdf
  18. python csv模块安装_Python中CSV模块
  19. 用Excel仿制了一个玫瑰图!
  20. 腾达无线路由器网关和域名服务器,腾达(Tenda)A6无线路由器路由模式设置上网

热门文章

  1. SQL Server 分隔字符串函数实现
  2. 炸!多线程 建议观看带上花生啤酒
  3. 表情包项目的另类玩法,月赚好几W,情感萌宠精准拿捏用户
  4. c语言直角梯形图案,html – 带有直角梯形的盒子形状
  5. 计算机教师格言座右铭,适合教师的格言座右铭
  6. ssh免密钥登录(两种方法) 免秘钥
  7. 2009全民健身日全国青少年攀岩赛(杭州站)开始报名!
  8. 曾经的梦想天真无邪,后来满脑子都是为了钱
  9. 为什么互联网流行 996 而非886、776
  10. 如何对电子邮件进行追踪?