2020CCPC长春F. Strange Memory
题目大意
一棵以 \(1\) 为根的 \(n(2\leq n\leq 10^5)\) 的树,每个节点 \(i\) 有权值 \(a_{i}(1\leq a_{i}\leq 10^6)\) ,求 \(\sum_{i=1}^{n}\sum_{j=i+1}^{n}[a_{i}\oplus a_{j}=a_{lca(i,j)}](i\oplus j)\) 。
思路
考虑 \(dsu\space on\space tree\) ,因为 \(a_{i}>0\) ,所以能够产生贡献的节点 \((i,j)\) 一定分属 \(lca(i,j)\) 两侧,于是计算各个子树的贡献时,考虑到对于每个节点 \(x\) ,对其中一棵子树中的节点 \(i\) , 其他子树中的每一个 \(a_{j} = a_{i}\oplus a_{x}\) 的节点 \(j\) 就会对答案产生 \(i\oplus j\) 的贡献。所以我们可以用一个数组 \(f[a,b,c]\) 来记录当权值为 \(a\) 时,该权值的节点编号在二进制中第 \(b\) 为的数字为 \(c\) 的节点个数,然后我们就可以对 \(i\) 来按位枚举有多少 \(j\) 能够对答案在这一位上产生贡献来计算答案。我们先计算所有轻子树内的答案,然后去掉轻子树对 \(f\) 的贡献,之后计算重子数的答案,之后保留其对 \(f\) 的贡献,再遍历所有子树,计算 \(f\) 以及跨子树的节点的答案,最后全部加起来即可。复杂度 \(O(nlogn)\) 。
代码
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
#define all(x) x.begin(),x.end()
//#define int LL
//#define lc p*2+1
//#define rc p*2+2
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-8;
const LL MOD = 1000000007;
const LL mod = 998244353;
const int maxn = 100010;
int N, A[maxn];
vector<int>G[maxn];
int vsize[maxn], hson[maxn], L[maxn], R[maxn], rnk[maxn], tot = 0;
LL tmp;
int f[1 << 20][20][2];
void add_edge(int from, int to)
{
G[from].push_back(to);
G[to].push_back(from);
}
void add(int v, int t)
{
for (int i = 19; i >= 0; i--)
f[A[v]][i][(v >> i) & 1] += t;
}
void dfs(int v,int p)
{
hson[v] = 0;
L[v] = ++tot;
rnk[tot] = v;
vsize[v] = 1;
for (int i = 0; i < G[v].size(); i++)
{
int to = G[v][i];
if (to == p)
continue;
dfs(to, v);
vsize[v] += vsize[to];
if (!hson[v] || vsize[to] > vsize[hson[v]])
hson[v] = to;
}
R[v] = tot;
}
void dsu(int v, int p)
{
for (int i = 0; i < G[v].size(); i++)
{
int to = G[v][i];
if (to == p || to == hson[v])
continue;
dsu(to, v);//单个子树内的贡献
for (int j = L[to]; j <= R[to]; j++)
add(rnk[j], -1);//清空计数信息
}
if (hson[v])
dsu(hson[v], v);
for (int i = 0; i < G[v].size(); i++)
{
int to = G[v][i];
if (to == p || to == hson[v])
continue;
for (int j = L[to]; j <= R[to]; j++)
{
int tar = A[rnk[j]] ^ A[v];
for (int i = 19; i >= 0; i--)
tmp += (1LL << i) * (LL)f[tar][i][((rnk[j] >> i) & 1) ^ 1];
}
for (int j = L[to]; j <= R[to]; j++)
add(rnk[j], 1);
}
add(v, 1);//加上自己的计数信息
}
void solve()
{
dfs(1, 0), dsu(1, 0);
cout << tmp << endl;
}
int main()
{
IOS;
cin >> N;
for (int i = 1; i <= N; i++)
cin >> A[i];
int u, v;
for (int i = 1; i < N; i++)
{
cin >> u >> v;
add_edge(u, v);
}
solve();
return 0;
}
2020CCPC长春F. Strange Memory的更多相关文章
- 数论F - Strange Way to Express Integers(不互素的的中国剩余定理)
F - Strange Way to Express Integers Time Limit:1000MS Memory Limit:131072KB 64bit IO Format: ...
- 2020CCPC长春题解 I - Kawaii Courier
2020CCPC长春题解 I - Kawaii Courier 题目大意:给一个树,让你求每个节点走到根节点的期望的d*x^d,d为走过的边个数.走法是每次随机等概率走到相邻的点. 题目分析: 相对于 ...
- ccpc2020长春站F题 Strange Memory
dsu on tree 题目链接 点我跳转 题目大意 给定一棵包含 \(n\) 个节点的树,每个节点有个权值 \(a_i\) 求\(∑_{i=1}^n∑_{j=i+1}^n[a_i⊕a_j=a_{lc ...
- CCPC 2020 长春站 部分简略题解
gym链接:CCPC 2020 changchun site A: 题目大意:商店里有若干个充值档位和首充奖励,你有\(n\)块钱问最多能拿到多少水. 解:由于档位不多可以直接枚举,整个二进制枚举一下 ...
- solidity中的memory和 storage详解
Solidity是一种智能合约高级语言,运行在Ethereum虚拟机(EVM)之上.这里我会讲解一下关键字storage和memory的区别. storage的结构是在合约部署创建时,根据你的合约中状 ...
- 内存模型 Memory model 内存分布及程序运行中(BSS段、数据段、代码段、堆栈
C语言中内存分布及程序运行中(BSS段.数据段.代码段.堆栈) - 秦宝艳的个人页面 - 开源中国 https://my.oschina.net/pollybl1255/blog/140323 Mem ...
- Java Magic. Part 4: sun.misc.Unsafe
Java Magic. Part 4: sun.misc.Unsafe @(Base)[JDK, Unsafe, magic, 黑魔法] 转载请写明:原文地址 系列文章: -Java Magic. P ...
- WebForm在JS中从Dropdownlist添加数据,在C#段读取
(1)页面设置和JS代码 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Def ...
- 原版本的jquery 开发过程中发现jquery好像更新了
/*! jQuery v1.7.1 jquery.com | jquery.org/license */ (function(a,b){function cy(a){return f.isWindow ...
随机推荐
- CSS基本语法(三)
目录 CSS基础语法(三) 十五.CSS定位 1.为什么要使用定位 2.定位组成 定位模式 静态定位 相对定位 绝对定位** 固定定位 粘性定位 边偏移 子绝父相 3.定位的叠放次序 4.拓展 绝对定 ...
- python操作MySQL数据库连接
目录 一:python操作MySQL 1.python如何操作MySQL? 2.什么是 PyMySQL? 二:PyMySQL 安装 1.方法一: 2.方法二: 三:pyMySQL模块基本使用 1.py ...
- 洛谷P1002过河卒java100分题解
题目描述如图: 这道题我以前以回溯的方法做,只能拿到60分 现在才发现是道动态规划题 解题思路: 创建一个(0,0)到终点打小的二维数组表示棋盘 每个坐标的值为此位置到终点的路数 最下方一排和最右方一 ...
- springboot 使用select的注解,来查询数据库。
package com.aaa.zxf.mapper; import com.aaa.zxf.model.Book; import org.apache.ibatis.annotations.*; i ...
- Sklearn 与 TensorFlow 机器学习实用指南第二版
零.前言 一.机器学习概览 二.一个完整的机器学习项目 三.分类 四.训练模型 五.支持向量机 六.决策树 七.集成学习和随机森林 八.降维 十.使用 Keras 搭建人工神经网络 十一.训练深度神经 ...
- 新一代Python包管理工具来了
1 简介 说起Python的包管理工具,大家第一时间想到的肯定是pip.conda等经典工具.但最近我发现了一款新颖的Python包管理工具--pdm,它受到PEP582(https://www.py ...
- AT2163 [AGC006B] Median Pyramid Easy
需要一点灵感的题目. 可以发现这样一个事情,当三个数中有两个数相同时,中为数一定是这两个相同的数. 基于这个观察,我们想让每一行都存在这样两个相同的两个数,就一定能保证第一层的值为 \(x\) 了. ...
- EKS助力小白实践云原生——通过k8s部署wordpress应用
目前云原生在大厂已经有了充分的实践,也逐渐向小厂以及非互联网公司推广.适逢12月20日,腾讯云原生[燎原社]精心打造了云原生在线技术工坊,让零基础的同学也能快速入门和实践 Docker 和 Kuber ...
- JAVA多线程学习十六 - 同步集合类的应用
1.引言 在多线程的环境中,如果想要使用容器类,就需要注意所使用的容器类是否是线程安全的.在最早开始,人们一般都在使用同步容器(Vector,HashTable),其基本的原理,就是针对容器的每一个操 ...
- 利用.htaccess隐藏html和php后缀
假设有个网页http://www.example.com/index.html或者http://www.example.com/index.php.如果我们想要隐藏.html后缀或者.php后缀,那么 ...