题目大意

一棵以 \(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的更多相关文章

  1. 数论F - Strange Way to Express Integers(不互素的的中国剩余定理)

    F - Strange Way to Express Integers Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format: ...

  2. 2020CCPC长春题解 I - Kawaii Courier

    2020CCPC长春题解 I - Kawaii Courier 题目大意:给一个树,让你求每个节点走到根节点的期望的d*x^d,d为走过的边个数.走法是每次随机等概率走到相邻的点. 题目分析: 相对于 ...

  3. ccpc2020长春站F题 Strange Memory

    dsu on tree 题目链接 点我跳转 题目大意 给定一棵包含 \(n\) 个节点的树,每个节点有个权值 \(a_i\) 求\(∑_{i=1}^n∑_{j=i+1}^n[a_i⊕a_j=a_{lc ...

  4. CCPC 2020 长春站 部分简略题解

    gym链接:CCPC 2020 changchun site A: 题目大意:商店里有若干个充值档位和首充奖励,你有\(n\)块钱问最多能拿到多少水. 解:由于档位不多可以直接枚举,整个二进制枚举一下 ...

  5. solidity中的memory和 storage详解

    Solidity是一种智能合约高级语言,运行在Ethereum虚拟机(EVM)之上.这里我会讲解一下关键字storage和memory的区别. storage的结构是在合约部署创建时,根据你的合约中状 ...

  6. 内存模型 Memory model 内存分布及程序运行中(BSS段、数据段、代码段、堆栈

    C语言中内存分布及程序运行中(BSS段.数据段.代码段.堆栈) - 秦宝艳的个人页面 - 开源中国 https://my.oschina.net/pollybl1255/blog/140323 Mem ...

  7. Java Magic. Part 4: sun.misc.Unsafe

    Java Magic. Part 4: sun.misc.Unsafe @(Base)[JDK, Unsafe, magic, 黑魔法] 转载请写明:原文地址 系列文章: -Java Magic. P ...

  8. WebForm在JS中从Dropdownlist添加数据,在C#段读取

    (1)页面设置和JS代码 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Def ...

  9. 原版本的jquery 开发过程中发现jquery好像更新了

    /*! jQuery v1.7.1 jquery.com | jquery.org/license */ (function(a,b){function cy(a){return f.isWindow ...

随机推荐

  1. Python36 使用Redis 构建分布式爬虫(未完)

    很长时间未更新了,人懒了. 最近有不少的东西,慢慢写吧,最近尝试了一下python 使用Redis 来构建分布式爬虫: 单体爬虫有很多缺点,但是在学习过程中能够学习爬虫的基本理念与运行模式,在后期构建 ...

  2. 集合框架-ArrayList练习(去除ArrayList集合中的重复元素)

    1 package cn.itcast.p3.arraylist.test; 2 3 import java.util.ArrayList; 4 import java.util.Iterator; ...

  3. 操作系统的发展史(并发与并行)<异步与同步>《进程与程序》[非堵塞与堵塞]

    目录 一:一:手工操作 -- 穿孔卡片 1.简介 二:手工操作方式两个特点: 三:批处理 -- 磁带存储 1.联机批处理系统 2.脱机批处理系统 3.多道程序系统 4.多道批处理系统 四:总结发展史 ...

  4. django之“static”全局设置

    1. 首先要配置静态文件路径(这些文件不输入任何app):. # 设置静态文件读取路径(这些静态文件不属于任何app) STATICFILES_DIRS = [ os.path.join(BASE_D ...

  5. CSS Modules 的六种用法

    一.局部作用域 二.全局作用域 三.定制哈希类名 四. Class 的组合 五.输入其他模块 六.输入变量

  6. Nginx 配置 HTTPS 服务器

    Nginx 配置 HTTPS 服务器 Chrome 浏览器地址栏标志着 HTTPS 的绿色小锁头从心理层面上可以给用户专业安全的心理暗示,本文简单总结一下如何在 Nginx 配置 HTTPS 服务器, ...

  7. Linux开机显示模式切换

    修改vim /etc/inittab 默认为5-图形界面模式,改为3-多用户模式即可 # Default runlevel. The runlevels used are: # 0 - halt (D ...

  8. MyEclipse工程中Java Build Path中的JDK版本和Java Compiler Compiler compliance level的区别

    感谢大佬:https://blog.csdn.net/shan9liang/article/details/17266519 问题起源: 今天再在ESB调用WebService测试,需要在jboss上 ...

  9. js判断当前浏览设备

    前端开发经常遇到需要判断用户的浏览设备,是pc端还是移动端,移动端使用的是什么手机系统?android.ios.ipad.windows phone等等,有时候还需要知道用户浏览页面是在微信中打开还是 ...

  10. iOS,蓝牙开发!!--By帮雷

    iOS的蓝牙开发大致有以下几种方式. 1 GameKit.framework [只能存在于iOS设备之间,多用于游戏 能搜索到的demo比较多,不确切说名字了,code4app里面就有] 2 Core ...