题目

子异和这个名字,真是思博

显然一个集合的子集异或和为,\(2^{|S|-1}\times A\),\(A\)为集合的或和

于是现在的问题变成了树链异或一个数,求树链或和

显然强行拆位是可以做的,复杂度\(O(n\log n\ \log mod)\),还是\(\rm lct\)于是直接飞了

通过一番玄妙重重的推理,我们发现,整体异或上\(c\),对或和的影响是

\[\cup'=(\cup\&∼c)|(c\&∼\cap)
\]

这样我们还需要维护与和

\[\cap'=(\cap\&∼c)|(c\&∼\cup)
\]

直接\(\rm lct\)维护即可,注意维护与和的时候记得判断当左右儿子为空时就不要取与了

代码

#include<bits/stdc++.h>
#define re register
#define LL long long
const int mod=1e9+7;
const int maxn=2e5+5;
#pragma GCC optimize(3)
#pragma GCC optimize("-fcse-skip-blocks")
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
unsigned int v[2][maxn],s[2],tag[maxn];
int ch[maxn][2],fa[maxn],sz[maxn],rev[maxn],st[maxn],a[maxn];
int xx[maxn],yy[maxn],pw[maxn],n,Q;
inline int nrt(int x) {return x==ch[fa[x]][0]||x==ch[fa[x]][1];}
inline void pushup(int x) {
sz[x]=1+sz[ch[x][0]]+sz[ch[x][1]];
v[1][x]=v[0][x]=a[x];
v[0][x]|=(v[0][ch[x][0]]|v[0][ch[x][1]]);
if(ch[x][0]) v[1][x]=(v[1][x]&v[1][ch[x][0]]);
if(ch[x][1]) v[1][x]=(v[1][x]&v[1][ch[x][1]]);
}
inline void calc(int x,unsigned int c) {
if(!x) return;
a[x]^=c,tag[x]^=c;
s[0]=v[0][x],s[1]=v[1][x];
v[0][x]=(s[0]&~c)|(c&~s[1]);
v[1][x]=(s[1]&~c)|(c&~s[0]);
}
inline void pushdown(int x) {
if(tag[x]) {
calc(ch[x][0],tag[x]),calc(ch[x][1],tag[x]);
tag[x]=0;
}
if(rev[x]) {
rev[x]=0,rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;
std::swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
std::swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
}
}
inline void rotate(int x) {
int y=fa[x],z=fa[y],k=ch[y][1]==x,w=ch[x][k^1];
if(nrt(y)) ch[z][ch[z][1]==y]=x;
ch[x][k^1]=y,ch[y][k]=w;
pushup(y),pushup(x);fa[w]=y,fa[y]=x,fa[x]=z;
}
inline void splay(int x) {
int y=x,top=0;st[++top]=x;
while(nrt(y)) y=fa[y],st[++top]=y;
while(top) pushdown(st[top--]);
while(nrt(x)) {
int y=fa[x];
if(nrt(y)) rotate((ch[y][1]==x)^(ch[fa[y]][1]==y)?x:y);
rotate(x);
}
}
inline void access(int x) {
for(re int y=0;x;y=x,x=fa[x])
splay(x),ch[x][1]=y,pushup(x);
}
inline void mrt(int x) {
access(x),splay(x),rev[x]^=1;std::swap(ch[x][0],ch[x][1]);
}
inline void split(int x,int y) {
mrt(x),access(y),splay(y);
}
inline void link(int x,int y) {
mrt(x),fa[x]=y;
}
int main() {
n=read();Q=read();
for(re int i=1;i<n;i++) xx[i]=read(),yy[i]=read();
for(re int i=1;i<=n;i++) a[i]=read(),sz[i]=1;
for(re int i=1;i<n;i++) link(xx[i],yy[i]);
pw[0]=1;int x,y,op;unsigned int c;
for(re int i=1;i<=n;++i) pw[i]=(pw[i-1]+pw[i-1])%mod;
while(Q--) {
op=read();x=read(),y=read();split(x,y);
if(op==1) printf("%d\n",1ll*v[0][y]%mod*pw[sz[y]-1]%mod);
else c=read(),calc(y,c);
}
return 0;
}

【LGP5127】子异和的更多相关文章

  1. 【转】Spring事务管理

    原文链接 在 Spring 中,事务是通过 TransactionDefinition 接口来定义的.该接口包含与事务属性有关的方法.具体如清单 1 所示: 清单 1. TransactionDefi ...

  2. 从源码看全局异常处理器@ExceptionHandler&@ExceptionHandler的生效原理

    1.开头在前 日常开发中,几乎我们的项目都会用到异常处理器,我们通常会定制属于自己的异常处理器,来处理项目中大大小小.各种各样的异常.配置异常处理器目前最常用的方式应该是使用@ControllerAd ...

  3. 机器学习——支持向量机(SVM)之拉格朗日乘子法,KKT条件以及简化版SMO算法分析

    SVM有很多实现,现在只关注其中最流行的一种实现,即序列最小优化(Sequential Minimal Optimization,SMO)算法,然后介绍如何使用一种核函数(kernel)的方式将SVM ...

  4. Java的位运算符详解实例——与(&)、非(~)、或(|)、异或(^)

    位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面 ...

  5. BRIEF 特征描述子

    Binary Robust Independent Elementary Features www.cnblogs.com/ronny 1. BRIEF的基本原理 我们已经知道SIFT特征采用了128 ...

  6. 《Xenogears》(异度装甲)隐含的原型与密码

    <Xenogears>(异度装甲)隐含的原型与密码 X 彩虹按:一种高次元的“生命体”,因“事故”被抓来当成“超能源”,其实那不只是“无限的能源”而已,“它”是有意志的!在我们眼里看来,这 ...

  7. [改善Java代码]数组的真实类型必须是泛型类型的子类型

    List接口的toArray方法可以把一个结合转化为数组,但是使用不方便,toArray()方法返回的是一个Object数组,所以需要自行转变. toArray(T[] a)虽然返回的是T类型的数组, ...

  8. HJA的异或值

    HJA的异或值 查看 提交 统计 提问 总时间限制:  20000ms 内存限制:  512000kB 描述 形态形成场(Morphogenetic Field)假说是Rupert Sheldrake ...

  9. [每日一题] OCP1z0-047 :2013-07-24 子查询――外查询与内查询的执行顺序

    一.Oracle的子查询分为两类分别是嵌套子查询和非嵌套子查询.所谓嵌套子查询是指,子查询是一个独立的查询不与外部查询相关,子查询将被先执行,而且只被执行一次,子查询执行完成后,再执行外部的查询,外部 ...

随机推荐

  1. STM32嵌入式开发学习笔记(三):使用按键控制小灯

    按键和小灯一样,也是通过GPIO外设与主板连接,也是通过GPIO_InitStruct类型结构体控制其工作. 查阅技术手册,按钮连接GPIOA控制下的管脚0. 但与之不同的是,按键是一种输入设备,输入 ...

  2. dom读写xml

    package com.xml; import java.io.File; import java.io.IOException; import javax.xml.crypto.dsig.Trans ...

  3. Appium 工作原理

    Appium - automation for mobile apps   一.Appium架构介绍 官网:www.appium.io 由SauceLab公司主持.并在Google的GATC2013会 ...

  4. Guava Spiltter类

    Splitter 提供了各种方法来处理分割操作字符串,对象等. 类声明 以下是com.google.common.base.Splitter类的声明: @GwtCompatible(emulated= ...

  5. js浮点数的计算总结

    在js浮点值的计算中,很多时候会出现不准确的情况,如下面的情况 console.log(2.2 + 2.1) // 4.300000000000001 console.log(2.2 - 1.9) / ...

  6. 使用Python将字符串转换为格式化的日期时间字符串

    我正在尝试将字符串“20091229050936”转换为“2009年12月29日(UTC)” >>>import time >>>s = time.strptime ...

  7. Oracle中NEXTVAL 和 CURRVAL的使用

    能够通过在 SQL 语句中使用 NEXTVAL 或 CURRVAL 运算符来訪问序列的值.必须用以 sequence.NEXTVAL 或sequence.CURRVAL 格式驻留在同一个数据库中的序列 ...

  8. 远程服务器安装nginx

    肯定有前端的小伙伴在腾讯云或者阿里云上购买了服务器,却不知道怎么访问使用它,那我们就一起来安装学习下? xshell 登录服务器,输入公网ip和密码登录 ls 查看目录,which nginx ,查看 ...

  9. docker容器和宿主机时间不一致的问题

    第1种:复制宿主机的localtime文件,到容器里docker cp /etc/localtime threg:/etc/ 注:这里 threg为容器名称,复制完后需重启容器 第2种在构建docke ...

  10. C语言指针函数和函数指针

    #include <stdio.h> char *test(); void test1(); int main() { /********************************* ...