Description

给你一个有n个点的树,每个点的包括一个位运算opt和一个权值x,位运算有&,l,^三种,分别用1,2,3表示。

每次询问包含三个数x,y,z,初始选定一个数v。然后v依次经过从x到y的所有节点,每经过一个点i,v就变成v opti

xi,所以他想问你,最后到y时,希望得到的值尽可能大,求最大值?给定的初始值v必须是在[0,z]之间。每次修

改包含三个数x,y,z,意思是把x点的操作修改为y,数值改为z。

Input

第一行三个数n,m,k。k的意义是每个点上的数,以及询问中的数值z都 <2^k。之后n行

每行两个数x,y表示该点的位运算编号以及数值

之后n - 1行,每行两个数x,y表示x和y之间有边相连

之后m行,每行四个数,Q,x,y,z表示这次操作为Q(1位询问,2为修改),x,y,z意义如题所述

0 <= n , m <= 100000 , k <= 64

Output

对于每个操作1,输出到最后可以造成的最大刺激度v

Sample Input

5 5 3

1 7

2 6

3 7

3 6

3 1

1 2

2 3

3 4

1 5

1 1 4 7

1 1 3 5

2 1 1 3

2 3 3 3

1 1 3 2

Sample Output

7

1

5

Sol

首先这题的核心思想就是把0和全集都过一遍,然后贪心选取,那么这道题就是在树上动态维护这样的操作。

树链剖分和LCT均可。

对于一个节点,我们维护这个点用全集经过以及用0经过的值。

显然可以开64个进行维护,但是这样会TLE。

设v0是0经过的结果,v1是全集经过的结果。

考虑所有位合并到一起进行,如果合并的话,那么公式就是:

(a.v0&b.v0)|(a.v0&b.v1),(a.v1&b.v0)|(a.v1&b.v1)

意义就是:要成为0的话,那么对于前面的a,a0中0的部分要经过b的0的部分并结合,已经是1的部分要经过b的1的部分并结合(这样才能保证合法),之后把这两种走法合并起来。

要成为1的话就要用a1去更新,同理。

因为位运算不满足交换律,所以还要维护两种方向的结果。

LCT的话在rev时还要记得交换l->r,r->l的值。

由于本人自带大常数,LCT自带大常数,bzoj还是老爷机,所以在bzojTLE了,luogu可以ac。

splay的时候记得注意合并顺序,坚决不能弄反。

初值就是\(0\quad opt\quad x\)以及\(全集全集\quad opt\quad x\)的结果啦,这样后面就不用考虑opt对合并的影响啦。

Code

#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
int n,m,op,x,y,rev[100005],fa[100005],c[100005][2];ull gg=0,z;
struct val{ull v0,v1;val(ull v0=0,ull v1=0):v0(v0),v1(v1){}}lr[100005],rl[100005],v[100005];
bool rt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
bool R(int x,int y){return c[x][1]==y;}
val merge(val a,val b){val c=val((~a.v0&b.v0)|(a.v0&b.v1),(~a.v1&b.v0)|(a.v1&b.v1));return c;}
void up(int x)
{
lr[x]=rl[x]=v[x];
if(c[x][0]) lr[x]=merge(lr[c[x][0]],lr[x]),rl[x]=merge(rl[x],rl[c[x][0]]);
if(c[x][1]) lr[x]=merge(lr[x],lr[c[x][1]]),rl[x]=merge(rl[c[x][1]],rl[x]);
}
void rever(int x){rev[x]^=1;swap(c[x][0],c[x][1]);swap(lr[x],rl[x]);}
void dn(int x){if(!rev[x]) return;rev[x]=0;rever(c[x][0]);rever(c[x][1]);}
void ud(int x){if(!rt(x)) ud(fa[x]);dn(x);}
void ro(int x)
{
int y=fa[x],z=fa[y],a=R(y,x),b=!a;
if(!rt(y)) c[z][R(z,y)]=x;
fa[x]=z;fa[y]=x;fa[c[x][b]]=y;c[y][a]=c[x][b];c[x][b]=y;up(y);up(x);
}
void spl(int x){ud(x);for(int y=fa[x],z=fa[y];!rt(x);ro(x),y=fa[x],z=fa[y])if(!rt(y))ro(R(z,y)^R(y,x)?y:x);}
void acs(int x){for(int y=0;x;y=x,x=fa[x]) spl(x),c[x][1]=y,up(x);}
void mrt(int x){acs(x);spl(x);rever(x);}
void lnk(int x,int y){mrt(x);fa[x]=y;}
ull query(int x,int y,ull z)
{
mrt(x);acs(y);spl(y);
ull ans=0,a0=lr[y].v0,a1=lr[y].v1,i;int k;
for(k=63,i=(1ull<<k);k>=0;i>>=1,k--){if(a0&i) ans+=i;else if((a1&i)&&z>=i) ans+=i,z-=i;}
return ans;
}
int main()
{
scanf("%d%d%*d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%llu",&op,&z);
if(op==1) v[i]=val(gg,z);if(op==2) v[i]=val(z,~gg);if(op==3) v[i]=val(z,~z);
}
for(int i=1;i<n;i++) scanf("%d%d",&x,&y),lnk(x,y);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%llu",&op,&x,&y,&z);
if(op==1){printf("%llu\n",query(x,y,z));continue;}else mrt(x);
if(y==1) v[x]=val(gg,z);if(y==2) v[x]=val(z,~gg);if(y==3) v[x]=val(z,~z);
up(x);
}
}

【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分/LCT+贪心的更多相关文章

  1. Luogu3613 睡觉困难综合征/BZOJ4811 Ynoi2017 由乃的OJ 树链剖分、贪心

    传送门 题意:给出一个$N$个点的树,树上每个点有一个位运算符号和一个数值.需要支持以下操作:修改一个点的位运算符号和数值,或者给出两个点$x,y$并给出一个上界$a$,可以选取一个$[0,a]$内的 ...

  2. BZOJ4811 [Ynoi2017]由乃的OJ 树链剖分

    原文链接http://www.cnblogs.com/zhouzhendong/p/8085286.html 题目传送门 - BZOJ4811 题意概括 是BZOJ3668长在树上并加上修改和区间询问 ...

  3. [BZOJ4811][YNOI2017]由乃的OJ(树链剖分+线段树)

    起床困难综合症那题,只要从高往低贪心,每次暴力跑一边看这一位输入0和1分别得到什么结果即可. 放到序列上且带修改,只要对每位维护一个线段树,每个节点分别记录0和1从左往右和从右往左走完这段区间后变成的 ...

  4. bzoj4811 [Ynoi2017]由乃的OJ 树链剖分+位运算

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4811 因为位运算的结果有可合并性,所以可以树链剖分,线段树维护: 细节很多,特别要注意从左往 ...

  5. bzoj4811 [Ynoi2017]由乃的OJ 树链剖分+贪心+二进制

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4811 题解 我现在为什么都写一题,调一天啊,马上真的退役不花一分钱了. 考虑这道题的弱化版 N ...

  6. 【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分+线段树区间合并

    题解: 好像和noi那题并没有什么区别 只是加上了修改和变成树上 比较显然我们可以用树链剖分来维护

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

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

  8. Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5020  Solved: 1872[Submit][Status ...

  9. Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 11102  Solved: 4490[Submit ...

随机推荐

  1. 服务器实现处理GET和POST

    import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.Inp ...

  2. DDD学习笔录——提炼问题域之有效提炼知识的模型(三)

    方式六:延迟对模型中概念的命名 对领域建模时命名很重要. 因为在不断的知识提炼过程中经常会发现已经被命名的概念与你最初理解的有出入,这时你当初的命名就会变成一个问题.其问题在于  最初选作名称的这个词 ...

  3. PHP 乘法口诀表

    echo "乘法口诀表<br>"; for($i=1;$i<10;$i++) { for ($j = 1; $j <= $i; $j++) printf(& ...

  4. sftp put权限不够

    报错如下: sftp> put play.zip ./ Uploading play.zip to /opt/library/./play.zip remote open("/opt/ ...

  5. MySQL与SQLServer的update left join语法区别

    需求: 表A 字段 A_ID, A_NAME, B_ID 表B 字段 B_ID, B_NAME 需求把A的所有A_NAME更新为相应的B的 B_NAME. mysql做法: UPDATE A LEFT ...

  6. Python函数之返回值、作用域和局部变量

    一.函数返回值 说到返回值,相信大家肯定都认识,没错,就是return. 所谓返回值可以这样理解:函数外部的代码要想获取函数的执行结果,就可以在函数里用return语句把结果返回. 那具体怎么用呢?接 ...

  7. Linux 搭建NFS文件服务器实现文件共享

    我们接着玩Linux,O(∩_∩)O哈哈~ 1.什么是nfs NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP ...

  8. 我的笔记,有关 PhotoShop,给自己的记忆宫殿

    一直有心学习 PhotoShop ,各种教程也 download 了不少,什么祁连山.PS大师之路.Oeasy 等等.看了吗?丫蛋的只看了前面两集!还是在博客上写写坐下笔记,好记性不如烂笔头. 0.先 ...

  9. Android 创建项目出现No resource found that matches the given name Theme.AppCompat.Light

    关于为何出现No resource found that matches the given name ‘Theme.AppCompat.Light’的原因 这边博客已经写的很清楚了 大家可以参考一下 ...

  10. cocos2d-x 在vs2010下的搭建(win7系统)

    1从官网下载cocos2d-x2.1.3的源码地址如下: http://cocos2d-x.org/ 2.解压下载的软件包我们会发现红框中vs2010的项目文件双击打开它 3.打开后我们要生成一些wi ...