博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P3613 睡觉困难综合征
阅读量:7072 次
发布时间:2019-06-28

本文共 3891 字,大约阅读时间需要 12 分钟。

题解

人生第一道由乃……

做这题之前应该先去把这一题给切掉->

我的题解->

然后先膜一波zsy大佬和flashhu大佬

大体思路就是先吧全0和全1的都跑答案,然后按位贪心

我一开始想到的是每一次split,然后直接一个一个跑

后来发现时间复杂度肯定爆炸……

看了看网上其他的,发现说的都不怎么清楚……结果硬是理解了好久才明白……

先考虑一下LCT维护什么

定义$f0$为全0走过一条路径之后的答案,$f1$表示全1走过一条路径之后的答案

LCT需要维护的是splay中以x为根的子树里,从前往后遍历(即中序遍历)的$f0$和$f1$以及从后往前(即与前面完全相反的顺序)的$f0$和$f1$

比如有一棵splay,x是其中一个点,它在splay中有两个儿子,左儿子y和右儿子z,那么从前往后遍历就是路径y->x->z,从后往前就是路径z->x->y

然后思考,如果已经有了两个区间,该如何合并他们

假如说我们有两段计算出答案的区间,分别对应f0,f1和g0,g1。我们设合并后的答案是h0,h1,那么有如下式子:

$h0=(~f0&g0)+(f0&g1)$

$h1=(~f1&g0)+(f1&g1)$

为啥?

全0走到最后的话,先考虑两种情况

全0走到中间等于1的那几位,走后一半的答案等同于全1走后一半的这几位的答案

全0走到中间等于0的那几位,走后一半的答案等同于全0走后一半的这几位的答案

只需要把这两个答案加起来即可

(ps:这里默认f为前一半的答案,g为后一半的答案)

全1走到最后同理

然后就是几个细节

1.pushdown的时候因为有翻转标记,从前往后走和从后往前走的答案也要交换

2.按位贪心用1做位运算的时候,记得把1设成unsigned long long(简单来说就是设一个ull变量让它等于1)(我就是因为一开始直接用1做位运算结果死都调不出来……)

1 // luogu-judger-enable-o2  2 //minamoto  3 #include
4 #include
5 #define ll unsigned long long 6 using std::swap; 7 using std::cout; 8 using std::endl; 9 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 10 char buf[1<<21],*p1=buf,*p2=buf; 11 inline ll read(){ 12 #define num ch-'0' 13 char ch;bool flag=0;ll res; 14 while(!isdigit(ch=getc())) 15 (ch=='-')&&(flag=true); 16 for(res=num;isdigit(ch=getc());res=res*10+num); 17 (flag)&&(res=-res); 18 #undef num 19 return res; 20 } 21 char obuf[1<<24],*o=obuf; 22 void print(ll x){ 23 if(x>9) print(x/10); 24 *o++=x%10+48; 25 } 26 const int N=100005; 27 struct node{ 28 ll f0,f1; 29 inline node operator +(const node &b)const 30 { 31 node a; 32 a.f0=(~f0&b.f0)|(f0&b.f1); 33 a.f1=(~f1&b.f0)|(f1&b.f1); 34 return a; 35 } 36 }f[N],l[N],r[N]; 37 int fa[N],ch[N][2],s[N],rev[N],top,tot; 38 int ver[N<<1],head[N],Next[N<<1]; 39 inline void add(int u,int v){ 40 ver[++tot]=v,Next[tot]=head[u],head[u]=tot; 41 ver[++tot]=u,Next[tot]=head[v],head[v]=tot; 42 } 43 inline bool isroot(int x){
return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} 44 #define ls ch[x][0] 45 #define rs ch[x][1] 46 inline void pushup(int x){ 47 l[x]=r[x]=f[x]; 48 if(ls) l[x]=l[ls]+l[x],r[x]=r[x]+r[ls]; 49 if(rs) l[x]=l[x]+l[rs],r[x]=r[rs]+r[x]; 50 } 51 inline void pushr(int x){ 52 swap(ls,rs),swap(l[x],r[x]),rev[x]^=1; 53 } 54 inline void pushdown(int x){ 55 if(rev[x]&&x){ 56 pushr(ls),pushr(rs),rev[x]=0; 57 } 58 } 59 void rotate(int x){ 60 int y=fa[x],z=fa[y],d=ch[y][1]==x; 61 if(!isroot(y)) ch[z][ch[z][1]==y]=x; 62 fa[x]=z,fa[y]=x,fa[ch[x][d^1]]=y,ch[y][d]=ch[x][d^1],ch[x][d^1]=y,pushup(y); 63 } 64 void splay(int x){ 65 s[top=1]=x;for(int i=x;!isroot(i);i=fa[i]) s[++top]=fa[i]; 66 while(top) pushdown(s[top--]); 67 for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){ 68 if(!isroot(y)) 69 ((ch[y][1]==x)^(ch[z][1]==y))?rotate(x):rotate(y); 70 rotate(x); 71 } 72 pushup(x); 73 } 74 void access(int x){ 75 for(int y=0;x;x=fa[y=x]){ 76 splay(x),rs=y,pushup(x); 77 } 78 } 79 void makeroot(int x){ 80 access(x),splay(x),pushr(x); 81 } 82 void split(int x,int y){ 83 makeroot(x),access(y),splay(y); 84 } 85 void dfs(int u){ 86 for(int i=head[u];i;i=Next[i]){ 87 int v=ver[i]; 88 if(v==fa[u]) continue; 89 fa[v]=u,dfs(v); 90 } 91 pushup(u); 92 } 93 int main(){ 94 //freopen("testdata.in","r",stdin); 95 int n=read(),m=read(),k=read(); 96 for(int i=1;i<=n;++i){ 97 int x=read();ll y=read(); 98 switch(x){ 99 case 1:f[i]=(node){
0,y};break;100 case 2:f[i]=(node){y,~0};break;101 case 3:f[i]=(node){y,~y};break;102 }103 }104 for(int i=1;i
=0;--i){113 if(l[y].f0&(e<
=(e<

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9430957.html

你可能感兴趣的文章
Jenkins+newman 控制台输出样式
查看>>
公司业务转型,IT基础架构也要转型,京东云Docker容器集群微服务实践
查看>>
解释try_files $uri $uri/ /index.php$is_args$args;
查看>>
营销圈也可以提供类似“不涂口红的你”的创意文案?
查看>>
【源码分享】短信验证码功能对接CmsEasy
查看>>
学习linux入门之top命令的用法介绍
查看>>
MySQL的基础分部
查看>>
aix knowlgdgecenter
查看>>
好程序员分享JavaScript事件委托代理和函数封装详解
查看>>
VMWARE 占用硬盘空间只增大不减少的清理办法
查看>>
oracle技术之系统触发器的应用顺序(三)
查看>>
oracle RMAN备份FORMAT格式中%a的含义
查看>>
Oracle11gr2数据泵新特性(四)
查看>>
Oracle 11g r2数据泵新特性(一)
查看>>
我的友情链接
查看>>
iftop的安装及使用
查看>>
redis学习笔记之发布订阅
查看>>
电商工作之外的学习途径
查看>>
python 之简单扯一扯time模块
查看>>
简单配置网页的404重定向
查看>>