题目


分析(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. 【LeetCode回溯算法#11】解数独,这次是真的用回溯法处理二维数组

    解数独 力扣题目链接(opens new window) 编写一个程序,通过填充空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出 ...

  2. 【Azure Function App】解决Function App For Container 遇见ServiceUnavailable的异常

    问题描述 在使用Terraform创建Function App 后,部署函数时候遇见 ServiceUnavailable (Bad Request -- Encountered an error ( ...

  3. 【Azure Redis 缓存】Lettuce 连接到Azure Redis服务,出现15分钟Timeout问题

    问题描述 在Java应用中,使用 Lettuce 作为客户端SDK与Azure Redis 服务连接,当遇见连接断开后,长达15分钟才会重连.导致应用在长达15分的时间,持续报错Timeout 问题解 ...

  4. 探索图片与Base64编码的优势与局限性

    一.图片和Base64编码的关系: 图片是一种常见的媒体文件格式,可以通过URL进行访问和加载. Base64编码是一种将二进制数据转换为ASCII字符的编码方式,可以将图片数据转换为字符串形式. 图 ...

  5. 50条MAUI踩坑记

    1. 目录结构: (1)_imports.razor是一个全局using namespace的地方 (2)Platforms下的代码,虽然都放在同一个项目下,但是Platforms\Android下的 ...

  6. RocketMQ(1) 基础介绍和单机-集群安装

    1. MQ简单介绍 1.1 应用场景 应用解耦 系统的耦合性越高,容错性就越低.以电商应用为例,用户创建订单后,如果耦合调用库存系统.物流系统.支付系统,任何一个子系统出了故障或者因为升级等原因暂时不 ...

  7. 基于python的生理电信号采集的数据转换和处理软件

    一 前记 团队开发了几款生物电信号采集系统,可数据处理和转换工具刚开始用的都是matlab.这对一些客户来说,使用门槛还是有些高了.开发一套配套的软件,满足广大用户的需求,已经是迫在眉睫的事情了.最近 ...

  8. 基于python下opuslib的下opus编解码实例解析

    一 opuslib 这个是纯粹的opus封装,要比ogg的那个更底层,ogg的那个封装的太严了.很多业务不方便开展. 二 实例解析: import opuslib import opuslib.api ...

  9. BigDecimal类处理高精度计算

    BigDecimal类处理高精度计算 Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数,但 ...

  10. vue通用的增删改查按钮组件

    代码复用:这个组件可以在多个页面或组件中使用,避免了重复编写相同的按钮代码. 灵活性:通过showButtons属性,可以根据需要显示不同的按钮.默认情况下,它会显示添加.修改和删除按钮,但你也可以根 ...