如果做过起床困难综合征的话应该很快就能有思路,没做过那道题的话还真是挺费劲的.

我们不知道要带入的值是什么,但是我们可以知道假设带入值得当前位为 $1$ 时这一位在经过位运算后是否为 $1$.

至于这个怎么维护,我们开两个变量 $f0,f1$ 代表初始带入全 $0$,全 $1$ 时每一位得值.

然后在 $LCT$ 中维护从左向右,从右向左两个方向上得这个东西,注意一下 $pushup$ 函数得写法.

这段代码十分优美,利用了按位取反等骚操作:

  1. struct node
  2. {
  3. ll f0,f1;
  4. node operator+(const node &b) const
  5. {
  6. node a;
  7. a.f0=(~f0&b.f0)|(f0&b.f1);
  8. a.f1=(~f1&b.f0)|(f1&b.f1);
  9. return a;
  10. }
  11. }f[N],L[N],R[N];

code:

  1. #include <bits/stdc++.h>
  2. #define N 100007
  3. #define ll unsigned long long
  4. #define setIO(s) freopen(s".in","r",stdin) ,freopen(s".out","w",stdout)
  5. using namespace std;
  6. int n,m,k,edges;
  7. int hd[N],to[N<<1],nex[N<<1];
  8. void addedge(int u,int v)
  9. {
  10. nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
  11. }
  12. struct node
  13. {
  14. ll f0,f1;
  15. node operator+(const node &b) const
  16. {
  17. node a;
  18. a.f0=(~f0&b.f0)|(f0&b.f1);
  19. a.f1=(~f1&b.f0)|(f1&b.f1);
  20. return a;
  21. }
  22. }f[N],L[N],R[N];
  23. struct Link_Cut_Tree
  24. {
  25. #define lson p[x].ch[0]
  26. #define rson p[x].ch[1]
  27. int sta[N];
  28. struct Node
  29. {
  30. int ch[2],f,rev;
  31. }p[N];
  32. int get(int x)
  33. {
  34. return p[p[x].f].ch[1]==x;
  35. }
  36. int isrt(int x)
  37. {
  38. return !(p[p[x].f].ch[0]==x||p[p[x].f].ch[1]==x);
  39. }
  40. void pushup(int x)
  41. {
  42. L[x]=R[x]=f[x];
  43. if(lson) L[x]=L[lson]+L[x], R[x]=R[x]+R[lson];
  44. if(rson) L[x]=L[x]+L[rson], R[x]=R[rson]+R[x];
  45. }
  46. void rotate(int x)
  47. {
  48. int old=p[x].f,fold=p[old].f,which=get(x);
  49. if(!isrt(old)) p[fold].ch[p[fold].ch[1]==old]=x;
  50. p[old].ch[which]=p[x].ch[which^1],p[p[old].ch[which]].f=old;
  51. p[x].ch[which^1]=old,p[old].f=x,p[x].f=fold;
  52. pushup(old),pushup(x);
  53. }
  54. void mark(int x)
  55. {
  56. if(!x) return;
  57. swap(lson,rson), swap(L[x],R[x]),p[x].rev^=1;
  58. }
  59. void pushdown(int x)
  60. {
  61. if(p[x].rev)
  62. {
  63. p[x].rev=0;
  64. if(lson) mark(lson);
  65. if(rson) mark(rson);
  66. }
  67. }
  68. void splay(int x)
  69. {
  70. int u=x,v=0,fa;
  71. for(sta[++v]=u;!isrt(u);u=p[u].f) sta[++v]=p[u].f;
  72. for(;v;--v) pushdown(sta[v]);
  73. for(u=p[u].f;(fa=p[x].f)!=u;rotate(x))
  74. if(p[fa].f!=u)
  75. rotate(get(fa)==get(x)?fa:x);
  76. }
  77. void Access(int x)
  78. {
  79. for(int y=0;x;y=x,x=p[x].f)
  80. {
  81. splay(x);
  82. rson=y;
  83. pushup(x);
  84. }
  85. }
  86. void makeroot(int x)
  87. {
  88. Access(x),splay(x),mark(x);
  89. }
  90. void split(int x,int y)
  91. {
  92. makeroot(x), Access(y), splay(y);
  93. }
  94. void link(int x,int y)
  95. {
  96. makeroot(x), p[x].f=y;
  97. }
  98. void cut(int x,int y)
  99. {
  100. makeroot(x),Access(y),splay(y);
  101. p[y].ch[0]=p[x].f=0;
  102. pushup(y);
  103. }
  104. #undef lson
  105. #undef rson
  106. }lct;
  107. void solve(int x,int y,ll z)
  108. {
  109. lct.split(x,y);
  110. int i;
  111. ll re=0;
  112. for(i=k-1;i>=0;--i)
  113. {
  114. if(L[y].f0&(1ll<<i)) re+=(1ll<<i);
  115. else if((L[y].f1&(1ll<<i)) && (1ll<<i)<=z) re+=(1ll<<i), z-=(1ll<<i);
  116. }
  117. printf("%llu\n",re);
  118. }
  119. void dfs(int u,int ff)
  120. {
  121. lct.p[u].f=ff;
  122. for(int i=hd[u];i;i=nex[i])
  123. if(to[i]!=ff) dfs(to[i],u);
  124. }
  125. int main()
  126. {
  127. int i,j;
  128. // setIO("input");
  129. scanf("%d%d%d",&n,&m,&k);
  130. for(i=1;i<=n;++i)
  131. {
  132. int op;
  133. ll y;
  134. scanf("%d%llu",&op,&y);
  135. if(op==1) f[i]=(node){0ll,y};
  136. if(op==2) f[i]=(node){y,~0ll};
  137. if(op==3) f[i]=(node){y,~y};
  138. lct.pushup(i);
  139. }
  140. for(i=1;i<n;++i)
  141. {
  142. int u,v;
  143. scanf("%d%d",&u,&v),addedge(u,v),addedge(v,u);
  144. }
  145. dfs(1,0);
  146. for(i=1;i<=m;++i)
  147. {
  148. int op;
  149. scanf("%d",&op);
  150. if(op==1)
  151. {
  152. int x,y;
  153. ll z;
  154. scanf("%d%d%llu",&x,&y,&z);
  155. solve(x,y,z);
  156. }
  157. else
  158. {
  159. int x,y;
  160. ll z;
  161. scanf("%d%d%llu",&x,&y,&z);
  162. lct.Access(x);
  163. lct.splay(x);
  164. if(y==1) f[x]=(node){0ll,z};
  165. if(y==2) f[x]=(node){z,~0ll};
  166. if(y==3) f[x]=(node){z,~z};
  167. lct.pushup(x);
  168. }
  169. }
  170. return 0;
  171. }

  

luogu 5354 [Ynoi2017]由乃的OJ LCT+位运算的更多相关文章

  1. Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算)

    Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算) Description T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放 ...

  2. P3613 睡觉困难综合征(LCT + 位运算)

    题意 NOI2014 起床困难综合症 放在树上,加上单点修改与链上查询. 题解 类似于原题,我们只需要求出 \(0\) 和 \(2^{k - 1} - 1\) 走过这条链会变成什么值,就能确定每一位为 ...

  3. Luogu P5354 [Ynoi2017]由乃的OJ

    题目 这题以前叫睡觉困难综合征. 首先我们需要知道起床困难综合征怎么做. 大概就是先用一个全\(0\)和全\(1\)的变量跑一遍处理出每一位\(1\)和\(0\)最后会变成什么. 然后高位贪心:如果当 ...

  4. Luogu P2114[NOI2014]起床困难综合症 【贪心/位运算】By cellur925

    题目传送门 所以NOI的题现在简单惹? 30分做法:枚举开始的权值,n²过掉. 100分做法:竟然是贪心qwq.因为我们的计算背景是二进制下,所以我们贪心地想让每一位都是1.我们现在需要解决的问题,就 ...

  5. 【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分/LCT+贪心

    Description 给你一个有n个点的树,每个点的包括一个位运算opt和一个权值x,位运算有&,l,^三种,分别用1,2,3表示. 每次询问包含三个数x,y,z,初始选定一个数v.然后v依 ...

  6. 【BZOJ4811】[Ynoi2017]由乃的OJ 树链剖分+线段树

    [BZOJ4811][Ynoi2017]由乃的OJ Description 由乃正在做她的OJ.现在她在处理OJ上的用户排名问题.OJ上注册了n个用户,编号为1-",一开始他们按照编号排名. ...

  7. [Ynoi2017]由乃的OJ

    题意 由乃正在做她的OJ.现在她在处理OJ上的用户排名问题.OJ上注册了n个用户,编号为1-",一开始他们按照编号 排名.由乃会按照心情对这些用户做以下四种操作,修改用户的排名和编号:然而由 ...

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

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

  9. luogu P3285 [SCOI2014]方伯伯的OJ splay 线段树

    LINK:方伯伯的OJ 一道稍有质量的线段树题目.不写LCT splay这辈子是不会单独写的 真的! 喜闻乐见的是 题目迷惑选手 \(op==1\) 查改用户在序列中的位置 题目压根没说位置啊 只有排 ...

随机推荐

  1. 编码方式之ASCII、ANSI、Unicode概述

    1.ASCII ASCII全称(American Standard Code for Information Interchange)美国信息交换标准代码,在计算机内部中8位二进制位组成1个字节(8( ...

  2. C++ 中不能声明为虚函数的函数有哪些?

    目录 普通函数 构造函数 内联成员函数 静态成员函数 友元函数 普通函数 普通函数(非成员函数)只能被overload,不能被override,而且编译器会在编译时绑定函数. 多态的运行期行为体现在虚 ...

  3. (一)easyUI之第一个demo

    一.下载 官网下载 : http://www.jeasyui.net/download/   同时并下载官方中文API文档. 解压后的目录结构: 二.第一个demo 1      新建工程并导入包 2 ...

  4. 关于hashcode 和 equals 的内容总结

    第一:equals() 的作用是 表示其他对象是否“等于”这个对象. 在Object源码里面    equals的作用等价于 ==   即 用来比较俩个对象的内存地址是否相同 public boole ...

  5. .htaccess 转 SAE AppConfig

    新浪的SAE不支持 htaccess,但是他们开发了 AppConfig,可以完全代替 htaccess 的常见功能,AppConfig采用类自然语言的规则描述,还是很人性化的. 这里来写一个短网址的 ...

  6. MySQL INNER JOIN子句介绍

    MySQL INNER JOIN子句介绍 MySQL INNER JOIN子句将一个表中的行与其他表中的行进行匹配,并允许从两个表中查询包含列的行记录. INNER JOIN子句是SELECT语句的可 ...

  7. HelenOS

    HelenOS 来源 http://www.helenos.org/ 关于HELENOS HelenOS是一种基于便携式微内核的多服务器操作系统,从头开始设计和实现.它将关键操作系统功能(如文件系统, ...

  8. 如何在含有json类型的字段上建立多列索引

    废话不多,直接上图 如 : 表结构如图           那么我想在这三个字段上建立一个唯一索引,目的是为了防止重复插入数据, 1.首先,说明一下 data中的json中,key为 tagID 和 ...

  9. 改写Unity DropDown 支持多次点击同一选项均回调

    [很久前的一个Note,不知道现在的Unity Dropdown是否已经支持该特性] Unity UGUI是开源的: https://bitbucket.org/Unity-Technologies/ ...

  10. Iterator 其实很简单(最好理解的工厂模式的例子)

    我们都知道Iterator是一个典型的工厂模式的例子.那么我们可能会被这两个名词搞晕.首先,我们会奇怪,为什么iterator可以遍历不同类型的结合,其次,出入程序猿的我们根本不知道工厂模式是什么. ...