洛谷P3613:睡觉困难综合征 (LCT+二进制压位)
来源:互联网 发布:防御矩阵无限金币 编辑:程序博客网 时间:2024/05/01 01:17
题目传送门:https://www.luogu.org/problemnew/show/P3613
题目分析:yuno好可爱呀!!!
由于不同的位运算之间不满足结合律,所以我们不能将后面的操作合并。又因为位运算时每一位是独立的,我们不妨考虑用LCT维护某一位开始是0,1时,经过这条链后会变成多少。询问时从高位向低位贪心:如果某一位可以选0或1,且选1比选0优,就选1,否则选0;还要注意最高位限制,有点像数位DP。
但每一位单独维护,时间是
由于我已经将近一个月没有打过LCT了,所以一个月前我切LCT像切菜一样,一个月后我切LCT像剁手一样。这道题我是2A的,原因是询问时,我Evert(x),Access(y)后,忘了Splay(Node[x])QAQ。
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;const int maxn=100100;typedef unsigned long long ULL;ULL Max;ULL Get(ULL x,ULL y,int op){ if (op==1) return (x&y); if (op==2) return (x|y); return (x^y);}ULL Rev(ULL x){ return (Max^x);}struct Tnode{ ULL f0,f1,g0,g1,val; int opt,path_parent; bool flip; Tnode *son[2],*fa; int Get_d() { return (fa->son[1]==this); } void Connect(Tnode *P,int d) { (son[d]=P)->fa=this; } void Push_down() { if (flip) { swap(son[0],son[1]); if (son[0]) { swap(son[0]->f0,son[0]->g0); swap(son[0]->f1,son[0]->g1); son[0]->flip^=1; } if (son[1]) { swap(son[1]->f0,son[1]->g0); swap(son[1]->f1,son[1]->g1); son[1]->flip^=1; } flip=false; } } void Up() { if (son[0]) f0=son[0]->f0,f1=son[0]->f1; else f0=0,f1=Max; f0=Get(f0,val,opt); f1=Get(f1,val,opt); if (son[1]) { ULL temp=(f0&son[1]->f1); temp|=(Rev(f0)&son[1]->f0); f0=temp; temp=(f1&son[1]->f1); temp|=(Rev(f1)&son[1]->f0); f1=temp; } if (son[1]) g0=son[1]->g0,g1=son[1]->g1; else g0=0,g1=Max; g0=Get(g0,val,opt); g1=Get(g1,val,opt); if (son[0]) { ULL temp=(g0&son[0]->g1); temp|=(Rev(g0)&son[0]->g0); g0=temp; temp=(g1&son[0]->g1); temp|=(Rev(g1)&son[0]->g0); g1=temp; } }} tree[maxn];Tnode *Node[maxn];int cur=-1;int n,m,k;Tnode *New_node(int op,ULL v){ cur++; tree[cur].val=v; tree[cur].opt=op; tree[cur].path_parent=0; tree[cur].flip=false; tree[cur].f0=tree[cur].g0=Get(0,v,op); tree[cur].f1=tree[cur].g1=Get(Max,v,op); tree[cur].fa=tree[cur].son[0]=tree[cur].son[1]=NULL; return tree+cur;}void Push(Tnode *P){ if (!P) return; Push(P->fa); P->Push_down();}void Zig(Tnode *P){ int d=P->Get_d(); Tnode *F=P->fa; if (P->son[!d]) F->Connect(P->son[!d],d); else F->son[d]=NULL; if (F->fa) F->fa->Connect(P, F->Get_d() ); else P->fa=NULL; P->Connect(F,!d); F->Up(); P->path_parent=F->path_parent; F->path_parent=0;}void Splay(Tnode *P){ Push(P); Tnode *F; while (P->fa) { F=P->fa; if (F->fa) ( P->Get_d()^F->Get_d() )? Zig(P):Zig(F); Zig(P); } P->Up();}void Down(int x){ Splay(Node[x]); Tnode *&tag=Node[x]->son[1]; if (tag) { tag->fa=NULL; tag->path_parent=x; tag=NULL; Node[x]->Up(); }}void Access(int x){ Down(x); Splay(Node[x]); int y=Node[x]->path_parent; while (y) { Down(y); Splay(Node[y]); Node[y]->Connect(Node[x],1); Node[y]->Up(); Node[x]->path_parent=0; x=y; y=Node[x]->path_parent; }}void Evert(int x){ Access(x); Splay(Node[x]); Node[x]->flip^=1; swap(Node[x]->f0,Node[x]->g0); swap(Node[x]->f1,Node[x]->g1);}void Link(int x,int y){ Evert(x); Splay(Node[x]); Node[x]->path_parent=y;}int main(){ freopen("3613.in","r",stdin); freopen("3613.out","w",stdout); scanf("%d%d%d",&n,&m,&k); Max=0; ULL temp=1; for (int i=0; i<k; i++) { Max|=temp; if (i<k-1) temp<<=1; } for (int i=1; i<=n; i++) { ULL v; int op; scanf("%d%llu",&op,&v); Node[i]=New_node(op,v); } for (int i=1; i<n; i++) { int x,y; scanf("%d%d",&x,&y); Link(x,y); } for (int i=1; i<=m; i++) { int id,x,y; ULL z; scanf("%d%d%d%llu",&id,&x,&y,&z); if (id==1) { Evert(x); Access(y); Splay(Node[x]); //!!!!! ULL v=temp,p=Node[x]->f0,q=Node[x]->f1,ans=0; bool High=false; while (v) { if ( (z&v) || High ) { if ( (q&v)>(p&v) ) ans|=(q&v); else ans|=(p&v),High=true; } else ans|=(p&v); v>>=1; } printf("%llu\n",ans); } else { Splay(Node[x]); Node[x]->opt=y; Node[x]->val=z; Node[x]->Up(); } } return 0;}
阅读全文
0 0
- 洛谷P3613:睡觉困难综合征 (LCT+二进制压位)
- luogu P3613 睡觉困难综合征
- 洛谷3613:睡觉困难综合症(LCT+机巧的位运算)
- 【树链剖分】LGP3613 睡觉困难综合征
- 【NOI 2014】起床困难综合征 拆位+贪心
- [BZOJ3668]NOI2014起床困难综合征|贪心
- [UOJ#2] [NOI2014] 起床困难综合征
- 2017.10.19 起床困难综合征 思考记录
- [NOI2014]起床困难综合症(二进制拆分+贪心)
- WikiOI 3311 起床困难综合症 (位运算)
- BZOJ4025(LCT+LCT+LinkCutTree)
- POJ -- 2443 Set Operation 【 二进制压位 】
- 睡觉
- 睡觉
- 睡觉
- 睡觉
- 睡觉
- 位运算(十进制转二进制)
- 八数码
- [SDS阅读理解/4]源码中的函数/1
- CSDN-markdown编辑器用法
- vsftpd安装手册
- Spark MLlib机器学习之朴素贝叶斯小试牛刀
- 洛谷P3613:睡觉困难综合征 (LCT+二进制压位)
- unity面试经历(一)
- Hive管理之Web界面和远程管理
- 一点点感悟
- C和指针之字符串编程练习9(在参数1中查找匹配参数2额任意字符)
- C++实现霍夫曼编码文件压缩解压
- springcloud好的学习地址
- Cash Machine POJ
- react native 之自定义顶部导航栏,实现标题居中可控