Luogu3613 睡觉困难综合征
2017-12-28 20:33
253 查看
题面描述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开始的。
比如说,有一个叫做1号节点的点,在以她为根的splay中还有点2,3,其中2是她的左儿子,3是她的右儿子,那么在1号点上维护的东西就应该是:依次经过2-1-3的最终结果,以及依次经过3-1-2的最终结果。
\[h0=(~f0&g0)+(f0&g1)\]
\[h1=(~f1&g0)+(f1&g1)\]
原因很简单,请自己YY~
原题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,那么有如下式子:\[h0=(~f0&g0)+(f0&g1)\]
\[h1=(~f1&g0)+(f1&g1)\]
原因很简单,请自己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 ,lo ,ro ; int n,m,fa ,ls ,rs ,rev ,Stack ,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 睡觉困难综合征(lct+贪心)
- luogu3613 睡觉困难综合征
- 洛谷P3613 睡觉困难综合征
- luogu P3613 睡觉困难综合征
- 【树链剖分】LGP3613 睡觉困难综合征
- [洛谷]P3613 睡觉困难综合征
- Luogu 睡觉困难综合征 ([NOI2014]起床困难综合症)
- [YNOI2017][bzoj4811][luogu3613] 由乃的OJ/睡觉困难综合症 [压位+树链剖分+线段树]
- 省队集训Day1 睡觉困难综合征
- 洛谷P3613 睡觉困难综合征
- 洛谷P3613:睡觉困难综合征 (LCT+二进制压位)
- 2017.10.19 起床困难综合征 思考记录
- 洛谷3613:睡觉困难综合症(LCT+机巧的位运算)
- [BZOJ3668]NOI2014起床困难综合征|贪心
- [UOJ#2] [NOI2014] 起床困难综合征
- [bzoj3668][Noi2014]起床困难综合症/[洛谷3613]睡觉困难综合症
- 【NOI 2014】起床困难综合征 拆位+贪心
- 证明连续函数的一致连续性为何那么困难?
- 看似简单实现起来却有困难的ARC设计目标