题目


分析(01trie)

考虑用trie做需要满足什么操作:加入某个数、01-Trie的合并、全局加一。

主要是全局加一比较难做,考虑改变的地方就是 \(X*2^T+2^T-1\)。

把01-Trie倒着建,那么全局加一只需要交换左右儿子并往原来的右儿子更新就可以了

再考虑这样建如何维护信息,那么就是 \(w[trie[x][0]]*2\) \(xor\) \(w[trie[x][1]]*2\) xor \(cnt[trie[x][1]]\)

也许这个能更好启发树上差分的做法吧


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int N=530011,M=N*21; long long Ans;
struct node{int y,next;}e[N]; bool _w[M];
int ans[N],a[N],as[N],n,cnt,trie[M][2],rt[N],w[M];
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void pup(int rt){
_w[rt]=_w[trie[rt][0]]^_w[trie[rt][1]];
w[rt]=(w[trie[rt][0]]^w[trie[rt][1]])<<1|_w[trie[rt][1]];
}
void update(int &rt,int x,int z){
if (!rt) rt=++cnt;
if (z>20){
_w[rt]^=1;
return;
}
update(trie[rt][(x>>z)&1],x,z+1);
pup(rt);
}
void one(int rt){
swap(trie[rt][0],trie[rt][1]);
if (trie[rt][0]) one(trie[rt][0]);
pup(rt);
}
int Merge(int fi,int se){
if (!fi||!se) return fi|se;
w[fi]^=w[se],_w[fi]^=_w[se];
trie[fi][0]=Merge(trie[fi][0],trie[se][0]);
trie[fi][1]=Merge(trie[fi][1],trie[se][1]);
return fi;
}
void dfs(int x){
for (int i=as[x];i;i=e[i].next)
dfs(e[i].y),rt[x]=Merge(rt[x],rt[e[i].y]);
one(rt[x]),update(rt[x],a[x],0);
ans[x]=w[rt[x]];
}
int main(){
n=iut();
for (int i=1;i<=n;++i) a[i]=iut();
for (int i=2;i<=n;++i){
int x=iut();
e[i]=(node){i,as[x]},as[x]=i;
}
dfs(1);
for (int i=1;i<=n;++i) Ans+=ans[i];
return !printf("%lld",Ans);
}

分析(树上差分)

改变的地方就是 \(X*2^T+2^T-1\),那么可以拆位考虑,

将子树的答案合并上来时,只有这些位置会改变。

如果记 \(a'_x=a_x+dep_x\),那么对于每个二进制位 子树中 \(dep_x\) 这个位置实则是要改变的,

因为插入 \(a_y+dep_x+1\) 后如果该值与 \(dep_x\) 在某个二进制位下与 \(2^i-1\) 同余那么它需要改变

树上差分就是用总的改变位置异或非子树改变位置即可


代码

#include <cstdio>
#include <cctype>
using namespace std;
const int N=530011; struct node{int y,next;}e[N];
int ans[N],a[N],as[N],w[N<<1][21],n,two[21]; long long Ans;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void dfs(int x,int d){
ans[x]=a[x];
for (int i=0;i<21;++i) w[(d+a[x])&(two[i]-1)][i]^=two[i];
for (int i=0;i<21;++i) ans[x]^=w[d&(two[i]-1)][i];
for (int i=as[x];i;i=e[i].next)
dfs(e[i].y,d+1),ans[x]^=ans[e[i].y];
for (int i=0;i<21;++i) ans[x]^=w[d&(two[i]-1)][i];
}
int main(){
n=iut(),two[0]=1;
for (int i=1;i<21;++i) two[i]=two[i-1]<<1;
for (int i=1;i<=n;++i) a[i]=iut();
for (int i=2;i<=n;++i){
int x=iut();
e[i]=(node){i,as[x]},as[x]=i;
}
dfs(1,0);
for (int i=1;i<=n;++i) Ans+=ans[i];
return !printf("%lld",Ans);
}

#树上差分 or 01-Trie#洛谷 6623 [省选联考 2020 A 卷] 树的更多相关文章

  1. 洛谷P6623——[省选联考 2020 A 卷] 树

    传送门:QAQQAQ 题意:自己看 思路:正解应该是线段树/trie树合并? 但是本蒟蒻啥也不会,就用了树上二次差分 (思路来源于https://www.luogu.com.cn/blog/dengy ...

  2. 洛谷 P6624 - [省选联考 2020 A 卷] 作业题(矩阵树定理+简单数论)

    题面传送门 u1s1 这种题目还是相当套路的罢 首先看到 \(\gcd\) 可以套路地往数论方向想,我们记 \(f_i\) 为满足边权的 \(\gcd\) 为 \(i\) 的倍数的所有生成树的权值之和 ...

  3. [题解] LOJ 3300 洛谷 P6620 [省选联考 2020 A 卷] 组合数问题 数学,第二类斯特林数,下降幂

    题目 题目里要求的是: \[\sum_{k=0}^n f(k) \times X^k \times \binom nk \] 这里面出现了给定的多项式,还有组合数,这种题目的套路就是先把给定的普通多项 ...

  4. luoguP6623 [省选联考 2020 A 卷] 树(trie树)

    luoguP6623 [省选联考 2020 A 卷] 树(trie树) Luogu 题外话: ...想不出来啥好说的了. 我认识的人基本都切这道题了. 就我只会10分暴力. 我是傻逼. 题解时间 先不 ...

  5. 洛谷 P7520 - [省选联考 2021 A 卷] 支配(支配树)

    洛谷题面传送门 真·支配树不 sb 的题. 首先题面已经疯狂暗示咱们建出支配树对吧,那咱就老老实实建呗.由于这题数据范围允许 \(n^2\)​ 算法通过,因此可以考虑 \(\mathcal O(n^2 ...

  6. 洛谷 P7515 - [省选联考 2021 A 卷] 矩阵游戏(差分约束)

    题面传送门 emmm--怎么评价这个题呢,赛后学完差分约束之后看题解感觉没那么 dl,可是现场为啥就因为种种原因想不到呢?显然是 wtcl( 先不考虑"非负"及" \(\ ...

  7. 洛谷 P7516 - [省选联考 2021 A/B 卷] 图函数(Floyd)

    洛谷题面传送门 一道需要发现一些简单的性质的中档题(不过可能这道题放在省选 D1T3 中偏简单了?) u1s1 现在已经是 \(1\text{s}\)​ \(10^9\)​ 的时代了吗?落伍了落伍了/ ...

  8. dp凸优化/wqs二分学习笔记(洛谷4383 [八省联考2018]林克卡特树lct)

    qwq 安利一个凸优化讲的比较好的博客 https://www.cnblogs.com/Gloid/p/9433783.html 但是他的暴力部分略微有点问题 qwq 我还是详细的讲一下这个题+这个知 ...

  9. 洛谷.4383.[八省联考2018]林克卡特树lct(树形DP 带权二分)

    题目链接 \(Description\) 给定一棵边带权的树.求删掉K条边.再连上K条权为0的边后,新树的最大直径. \(n,K\leq3\times10^5\). \(Solution\) 题目可以 ...

  10. 洛谷P4383 [八省联考2018]林克卡特树lct(DP凸优化/wqs二分)

    题目描述 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战. 游戏中有一个叫做“LCT” 的挑 ...

随机推荐

  1. redis7源码分析:redis 多线程模型解析

    多线程模式中,在main函数中会执行InitServerLast void InitServerLast() { bioInit(); // 关键一步, 这里启动了多条线程,用于执行命令,redis起 ...

  2. pikachu sql inject header 注入

    使用admin登录 显示以下内容 朋友,你好,你的信息已经被记录了:点击退出 你的ip地址:172.17.0.1 你的user agent:Mozilla/5.0 (X11; Ubuntu; Linu ...

  3. Redis客户端汇总

    编程客户端 已经支持了许多编程语言,详见:https://redis.io/docs/clients/ 图形客户端 1.Another Redis Desktop Manager 支持哨兵, 集群, ...

  4. Vue 3 的 setup语法糖到底是什么东西?

    前言 我们每天写vue3项目的时候都会使用setup语法糖,但是你有没有思考过下面几个问题.setup语法糖经过编译后是什么样子的?为什么在setup顶层定义的变量可以在template中可以直接使用 ...

  5. 02、NATS单节点部署

    接下来,我们一起看看如何部署一个单节点的 nats 服务器,这样后续学习 nats 的功能和特性的时候,会更加的清晰,那我们一起看看如何部署单节点的nats服务,后面在学习如何部署集群版的 nats. ...

  6. C语言之牛必克拉斯 main() 函数

    C语言之main()函数 C程序最大的特点就是所有的程序都是用函数来装配的.main()称之为主函数,是所有程序运行的入口.其余函数分为有参或无参两种,均由main()函数或其它一般函数调用,若调用的 ...

  7. 【主流技术】日常工作中关于 JSON 转换的经验大全(Java)

    目录 前言 一.JSON 回顾 1.1结构形式 二.其它类型 -> JSON相关 2.1 JavaBean 转 JsonObject 2.2 JavaBean 转 Json 字符串 2.3 Li ...

  8. mybatis查询大批量数据的几种方式

    问题背景 公司里有很多需要跑批数据的场景,这些数据几十万到几千万不等,目前我们采用的是分页查询,但是分页查询有个深度分页问题,上百万的数据就会查询的很慢 常规解决方案 全量查询 分页查询 流式查询 游 ...

  9. Zabbix6.0使用教程 (一)—zabbix新增功能介绍2

    上一篇我们已经介绍了部分zabbix6.0的新增功能,这期我们将继续为家详细介绍下余下的zabbix6.0新增功能,大家可以往下看. 六.监控项 6.1 自动类型选择 监控项配置表单会自动建议匹配的信 ...

  10. 使用Mockito与Squaretest进行单元测试.

    项目开发过程中,不少公司都要求写单元测试的代码,可以提高代码的质量,并且可以减少出现BUG的概率. 对于中小型公司来说,对单元测试不做硬性要求,不写最好.因为还是需要一定的工作量,在保证代码质量和性能 ...