【BZOJ2908】又是nand 树链剖分+线段树

【BZOJ2908】又是nand

escription

首先知道A nand B=not(A and B) (运算操作限制了数位位数为K)比如2 nand 3,K=3,则2 nand 3=not (2 and 3)=not 2=5。
给出一棵树,树上每个点都有点权,定义树上从a到b的费用为0与路径上的点的权值顺次nand的结果,例如:从2号点到5号点顺次经过2->3->5,权值分别为5、7、2,K=3,那么最终结果为0 nand 5 nand 7 nand 2=7 nand 7 nand 2=0 nand 2=7,现在这棵树需要支持以下操作。
①    Replace a b:将点a(1≤a≤N)的权值改为b。
②    Query a b:输出点a到点b的费用。
请众神给出一个程序支持这些操作。

Input

第一行N,M,K,树的节点数量、总操作个数和运算位数。
接下来一行N个数字,依次表示节点i的权值。
接下来N-1行,每行两个数字a,b(1≤a,b≤N)表示a,b间有一条树边。
接下来M行,每行一个操作,为以上2类操作之一。
N、M≤100000,K≤32

Output

对于操作②每个输出一行,如题目所述。

Sample Input

3 3 3
2 7 3
1 2
2 3
Query 2 3
Replace 1 3
Query 1 1

Sample Output

4
7

题解:网上都说要拆位,那么我也拆位吧~(不拆位好像也能做?)

首先,nand满足交换律但不满足结合律。

我们先树剖,然后对于每一位,都用线段树维护tl[d][x],代表如果该位是d,从左边来经过这个区间后会变成的数,tr[d][x]代表如果该位是d,从右往左经过这个区间后会变成的数。然后就是区间合并的事了~

对于询问a,b,我们先求出从a向上走到lca的变化,再求出从lca向下走到b的变化即可。

 

#include <cstdio>
#include <cstring>
#include <iostream>
#define lson x<<1
#define rson x<<1|1
using namespace std;
int n,m,k,cnt;
char str[10];
const int maxn=100010;
int to[maxn<<1],next[maxn<<1],head[maxn],fa[maxn],dep[maxn],siz[maxn],top[maxn],son[maxn],p[maxn],q[maxn],st[maxn];
unsigned v[maxn];
struct seg
{bool tl[2][maxn<<2],tr[2][maxn<<2];void pushup(int x){tl[0][x]=tl[tl[0][lson]][rson],tl[1][x]=tl[tl[1][lson]][rson];tr[0][x]=tr[tr[0][rson]][lson],tr[1][x]=tr[tr[1][rson]][lson];}void build(int l,int r,int x,int a){if(l==r){tl[0][x]=tr[0][x]=1,tl[1][x]=tr[1][x]=!((v[q[l]]>>a)&1);return ;}int mid=l+r>>1;build(l,mid,lson,a),build(mid+1,r,rson,a);pushup(x);}void updata(int l,int r,int x,int a,bool b){if(l==r){tl[0][x]=tr[0][x]=1,tl[1][x]=tr[1][x]=!b;return ;}int mid=l+r>>1;if(a<=mid)	updata(l,mid,lson,a,b);else	updata(mid+1,r,rson,a,b);pushup(x);}bool ql(int l,int r,int x,int a,int b,bool c){if(a<=l&&r<=b)	return tl[c][x];int mid=l+r>>1;if(b<=mid)	return ql(l,mid,lson,a,b,c);if(a>mid)	return ql(mid+1,r,rson,a,b,c);return ql(mid+1,r,rson,a,b,ql(l,mid,lson,a,b,c));}bool qr(int l,int r,int x,int a,int b,bool c){if(a<=l&&r<=b)	return tr[c][x];int mid=l+r>>1;if(b<=mid)	return qr(l,mid,lson,a,b,c);if(a>mid)	return qr(mid+1,r,rson,a,b,c);return qr(l,mid,lson,a,b,qr(mid+1,r,rson,a,b,c));}
}s[33];
inline int rd()
{int ret=0;	char gc=getchar();while(gc<'0'||gc>'9')	gc=getchar();while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();return ret;
}
void dfs1(int x)
{siz[x]=1;for(int i=head[x];i!=-1;i=next[i]){if(to[i]!=fa[x]){fa[to[i]]=x,dep[to[i]]=dep[x]+1,dfs1(to[i]),siz[x]+=siz[to[i]];if(siz[to[i]]>siz[son[x]])	son[x]=to[i];}}
}
void dfs2(int x,int tp)
{top[x]=tp,p[x]=++p[0],q[p[0]]=x;if(son[x])	dfs2(son[x],tp);for(int i=head[x];i!=-1;i=next[i])	if(to[i]!=fa[x]&&to[i]!=son[x])	dfs2(to[i],to[i]);
}
void add(int a,int b)
{to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
void ask(int x,int y)
{unsigned int ret=0;int i;st[0]=0;while(top[x]!=top[y]){if(dep[top[x]]>=dep[top[y]]){for(i=0;i<k;i++)	ret=ret-(ret&(1<<i))+(s[i].qr(1,n,1,p[top[x]],p[x],(ret>>i)&1)<<i);x=fa[top[x]];}else	st[++st[0]]=y,y=fa[top[y]];}if(dep[x]<dep[y])	for(i=0;i<k;i++)	ret=ret-(ret&(1<<i))+(s[i].ql(1,n,1,p[x],p[y],(ret>>i)&1)<<i);else	for(i=0;i<k;i++)	ret=ret-(ret&(1<<i))+(s[i].qr(1,n,1,p[y],p[x],(ret>>i)&1)<<i);for(y=st[0];y;y--)	for(i=0;i<k;i++)	ret=ret-(ret&(1<<i))+(s[i].ql(1,n,1,p[top[st[y]]],p[st[y]],(ret>>i)&1)<<i);printf("%u\n",ret);
}
int main()
{n=rd(),m=rd(),k=rd();int i,j,a,b;for(i=1;i<=n;i++)	scanf("%u",&v[i]);memset(head,-1,sizeof(head));for(i=1;i<n;i++)	a=rd(),b=rd(),add(a,b),add(b,a);dep[1]=1,dfs1(1),dfs2(1,1);for(i=0;i<k;i++)	s[i].build(1,n,1,i);for(i=1;i<=m;i++){scanf("%s",str);if(str[0]=='Q')	a=rd(),b=rd(),ask(a,b);else{a=rd(),scanf("%u",&v[a]);for(j=0;j<k;j++)	s[j].updata(1,n,1,p[a],(v[a]>>j)&1);}}return 0;
}//3 3 3 2 7 3  1 2 2 3 Query 2 3 Replace 1 3 Query 1 1  

 

转载于:https://www.cnblogs.com/CQzhangyu/p/7327672.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/428936.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1001 害死人不偿命的(3n+1)猜想 (15 分)

1001 害死人不偿命的(3n1)猜想 (15 分) 卡拉兹(Callatz)猜想&#xff1a; 对任何一个正整数 n&#xff0c;如果它是偶数&#xff0c;那么把它砍掉一半&#xff1b;如果它是奇数&#xff0c;那么把 (3n1) 砍掉一半。这样一直反复砍下去&#xff0c;最后一定在某一步得到 n1。卡…

2017安徽二级c语言,2017计算机二级C语言测试题及答案

2017计算机二级C语言测试题及答案此题 首先为整型变量赋初值x11,x22表达式1为i1&#xff0c;表达式2(循环条件)为i<N即i<4&#xff0c;表达式3为i循环变量初值i为1&#xff0c;循环条件(即表达式2)i<4成立&#xff0c;进入第1次循环第1次循环执行printf("%4d%4d&…

笔试被虐随想

两个题 50分钟&#xff0c;我写满时间还没写完一个。心疼自己。 算法渣。战五渣。 每天一个算法题吧。 至于工作&#xff0c;没什么好说的&#xff0c;加油吧&#xff0c;横竖算经验。转载于:https://www.cnblogs.com/bryanz/p/7330998.html

c语言如何不四舍五入取整函数,Excel四舍五入、不四舍五入或取整的相关函数

①ROUND函数1、四舍五入&#xff1a;ROUND(目标单元格&#xff0c;0)2、入&#xff1a;ROUNDUP(目标单元格&#xff0c;0) 得出来的结果是向上的整数&#xff0c;即&#xff1a;3.3543、舍&#xff1a;ROUNDDOWN(目标单元格&#xff0c;0)得出来的结果是向下的整数&#xff0c;…

1002 写出这个数 (20 分)

1002 写出这个数 (20 分) 读入一个正整数 n&#xff0c;计算其各位数字之和&#xff0c;用汉语拼音写出和的每一位数字。 输入格式&#xff1a; 每个测试输入包含 1 个测试用例&#xff0c;即给出自然数 n 的值。这里保证 n 小于 10 ​100 ​​ 。 输出格式&#xff1a; 在一…

E - More is better (并查集)

点击打开链接 Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements. Mr Wang selected a room big enough to hold the boys. The boy who ar…

c语言pwm调制方式,pwm调制原理同步调制_几种pwm调制方式介绍 - 全文

PWM简介脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术&#xff0c;广泛应用在从测量、通信到功率控制与变换的许多领域中。脉冲宽度调制是一种模拟控制方式&#xff0c;其根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置&#xff0c;来…

1003 我要通过! (20 分)

1003 我要通过&#xff01; (20 分) “答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件&#xff0c;系统就输出“答案正确”&#xff0c;否则输出“答案错误”。 得到“答案正确”的条件是&#xff1…

POJ 3613 Cow Relays (floyd + 矩阵高速幂)

题目大意&#xff1a; 求刚好经过K条路的最短路 我们知道假设一个矩阵A[i][j] 表示表示 i-j 是否可达 那么 A*AB B[i][j] 就表示 i-j 刚好走过两条路的方法数 那么同理 我们把i-j 的路径长度存到A 中。在A*A的过程中&#xff0c;不断取小的。那么最后得到的也就是i - j 走过…

c语言如何用循环语句一个字一个字的输出,怎样用c语言的for嵌套循环,用·画出泳字,求解,主要是怎样用循环语句打出,在某一行中既有空格又有·...

暗域天堂#include #include #include #include #include using namespace std;int get_character(unsigned char* pc1, unsigned char* pc2){unsigned char buf[100];cin >> buf;*pc1 buf[0];*pc2 buf[1];if (*pc1 {return -2;}if (*pc2 {return -2;}return 0;}void lo…

1004 成绩排名 (20 分)

1004 成绩排名 (20 分) 读入 n&#xff08;>0&#xff09;名学生的姓名、学号、成绩&#xff0c;分别输出成绩最高和成绩最低学生的姓名和学号。 输入格式&#xff1a; 每个测试输入包含 1 个测试用例&#xff0c;格式为 第 1 行&#xff1a;正整数 n 第 2 行&#xff1a…

【Sikuli】Sikuli 文档

http://sikulix-2014.readthedocs.io/en/latest/index.html转载于:https://www.cnblogs.com/MasterMonkInTemple/p/7346480.html

c语言赋值运算符左边必须是,C语言运算符入门讲解

概述C 语言运算符分为算术、关系、逻辑、赋值、逗号和 sizeof 5 大类。表达式&#xff1a;在 C/C 中&#xff0c;用运算符将操作对象连接起来就构成了表达式。表达式是用于计算的式子&#xff0c;是计算求值的基本单位。操作对象&#xff1a;又称操作数&#xff0c;操作数可以为…

1005 继续(3n+1)猜想 (25 分)

1005 继续(3n1)猜想 (25 分) 卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里&#xff0c;情况稍微有些复杂。 当我们验证卡拉兹猜想的时候&#xff0c;为了避免重复计算&#xff0c;可以记录下递推过程中遇到的每一个数。例如对 n3 进行验证的时候&#xff0c;我们…

MSYS2使用教程

一、安装 官方下载地址 http://www.msys2.org/ 指定好安装路径&#xff08;一般D根目录即可&#xff09;&#xff0c;一路下一步就好。 二、配置国内镜像、设置窗体修改颜色 使用[清华大学开源软件镜像站]中的地址&#xff0c;修改\etc\pacman.d目录下的三个文件。 配置教程 ht…

c语言mc协议,easymc - C语言开发的简易消息通道库

easymc是一个C语言开发的简易的消息通道库&#xff0c;目前提供请求/回应、订阅/发布两种通信模式&#xff0c;同机器的通信采取IPC方式&#xff0c;跨机的通信采取TCP方式&#xff0c;源码包含开源项目jemalloc库。代码地址&#xff1a;https://github.com/easymc/easymclocal…

1006 换个格式输出整数 (15 分)

1006 换个格式输出整数 (15 分)让我们用字母 B 来表示“百”、字母 S 表示“十”&#xff0c;用 12…n 来表示不为零的个位数字 n&#xff08;<10&#xff09;&#xff0c;换个格式来输出任一个不超过 3 位的正整数。例如 234 应该被输出为 BBSSS1234&#xff0c;因为它有 2…

android 复制字符串,Cocos2dx 复制文本到剪切板(Android 和 ios)

ClipboardManager cm (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);cm.setText(要复制的文本内容);源码分享&#xff1a;Cocos2dxHelper.java 中添加吧import android.content.ClipboardManager; //导入需要的库static public int copyToClipboard(final …

1007 素数对猜想 (20 分)

1007 素数对猜想 (20 分) 让我们定义d ​n ​​ 为&#xff1a;d ​n ​​ p ​n1 ​​ −p ​n ​​ &#xff0c;其中p ​i ​​ 是第i个素数。显然有d ​1 ​​ 1&#xff0c;且对于n>1有d ​n ​​ 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。 现…

[原创]浅谈移动互联网App兼容性测试

[原创]浅谈移动互联网App兼容性测试 今天要谈的话题&#xff0c;估计各位测试都有感受&#xff0c;移动互联网App兼容性测试&#xff0c;我们到底测试覆盖如何去挑选机型&#xff1f;具体移动App兼容性测试如何开展&#xff1f;是不是应引进像testin这样的第三方来检查覆盖?可…