HDU5589 Tree

题意:

给出一棵\(N\)个点的树,每条边有边权,每次询问下标为\([L,R]\)区间内的点能选出多少点对,点对之间的路径上的边权异或和大于\(M\)

题解:

对于两点\(u,v\)之间的路径上的边权的异或和,可以转化为根到点\(u\)的路径上异或和与根到点\(v\)的路径上异或和的异或和,所以可以与处理出根到各个点的路径边权异或和

接下来就变成了一个序列上的问题了,每次询问区间\([L,R]\)之间的点有多少对的异或和大于\(M\)

然后就可以用莫队来处理,为了能快速加值和删值还有查询,而且是异或的操作,这里选择用\(01\)字典树来做

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 5e4+7;
typedef long long int LL;
int n,m,q,w[MAXN];
LL ret[MAXN],ans;
struct Trie{
int tot,ch[MAXN<<4][2],cnt[MAXN<<4];
void clear(){
for(int i = 1; i <= tot; i++) ch[i][0] = ch[i][1] = cnt[i] = 0;
tot = 1;
}
void insert(int x, int now = 1){
for(int i = 19; i >= 0; i--){
if(!ch[now][(x>>i)&1]) ch[now][(x>>i)&1] = ++tot;
cnt[now = ch[now][(x>>i)&1]]++;
}
}
void erase(int x, int now = 1){
for(int i = 19; i >= 0; i--) cnt[now = ch[now][(x>>i)&1]]--;
}
int query(int x){
int ret = 0, now = 1;
for(int i = 19; i >= 0 and now; i--){
int bm = ((m>>i)&1);
int bx = ((x>>i)&1);
if(!bm) ret += cnt[ch[now][bx^1]], now = ch[now][bx];
else now = ch[now][bx^1];
}
return ret;
}
}trie;
struct Query{ int l, r, id; } Q[MAXN];
vector<pair<int,int>> G[MAXN];
void dfs(int u, int par){
for(auto e : G[u]) if(e.first!=par){
w[e.first] = w[u] ^ e.second;
dfs(e.first,u);
}
}
void inc(int x){
ans += trie.query(x);
trie.insert(x);
}
void dec(int x){
trie.erase(x);
ans -= trie.query(x);
}
void solve(){
for(int i = 1; i <= n; i++) G[i].clear();
for(int i = 1; i < n; i++){
int u, v, wt;
scanf("%d %d %d",&u,&v,&wt);
G[u].push_back(make_pair(v,wt)); G[v].push_back(make_pair(u,wt));
}
dfs(1,0); trie.clear();
for(int i = 1; i <= q; i++) scanf("%d %d",&Q[i].l,&Q[i].r), Q[i].id = i;
int sqt = sqrt(n);
sort(Q+1,Q+1+q,[&sqt](const Query &lhs, const Query &rhs){
return lhs.l / sqt == rhs.l / sqt ? lhs.r < rhs.r : lhs.l / sqt < rhs.l / sqt;
});
int L = 1, R = 0;
ans = 0;
for(int i = 1; i <= q; i++){
while(L>Q[i].l) inc(w[--L]);
while(R<Q[i].r) inc(w[++R]);
while(L<Q[i].l) dec(w[L++]);
while(R>Q[i].r) dec(w[R--]);
ret[Q[i].id] = ans;
}
for(int i = 1; i <= q; i++) printf("%I64d\n",ret[i]);
}
int main(){
while(scanf("%d %d %d",&n,&m,&q)!=EOF) solve();
return 0;
}

HDU5589 Tree【分块 01字典树】的更多相关文章

  1. HDU6191 Query on A Tre【dsu on tree + 01字典树】

    Query on A Tree Problem Description Monkey A lives on a tree, he always plays on this tree. One day, ...

  2. HDU 6191 2017ACM/ICPC广西邀请赛 J Query on A Tree 可持久化01字典树+dfs序

    题意 给一颗\(n\)个节点的带点权的树,以\(1\)为根节点,\(q\)次询问,每次询问给出2个数\(u\),\(x\),求\(u\)的子树中的点上的值与\(x\)异或的值最大为多少 分析 先dfs ...

  3. HDU6191 Query on A Tree (01字典树+启发式合并)

    题意: 给你一棵1e5的有根树,每个节点有点权,1e5个询问(u,x),问你子树u中与x异或最大的值是多少 思路: 自下而上启发式合并01字典树,注意合并时清空trie 线段树.字典树这种结构确定的数 ...

  4. HDU6191(01字典树启发式合并)

    Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Othe ...

  5. Chip Factory(01字典树)

    Chip Factory http://acm.hdu.edu.cn/showproblem.php?pid=5536 Time Limit: 18000/9000 MS (Java/Others)  ...

  6. 2014百度之星资格赛—— Xor Sum(01字典树)

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total ...

  7. AcWing:144. 最长异或值路径(dfs + 01字典树)

    给定一个树,树上的边都具有权值. 树中一条路径的异或长度被定义为路径上所有边的权值的异或和: ⊕ 为异或符号. 给定上述的具有n个节点的树,你能找到异或长度最大的路径吗? 输入格式 第一行包含整数n, ...

  8. AcWing:143. 最大异或对(01字典树 + 位运算 + 异或性质)

    在给定的N个整数A1,A2……ANA1,A2……AN中选出两个进行xor(异或)运算,得到的结果最大是多少? 输入格式 第一行输入一个整数N. 第二行输入N个整数A1A1-ANAN. 输出格式 输出一 ...

  9. Codeforces 979 D. Kuro and GCD and XOR and SUM(异或和,01字典树)

    Codeforces 979 D. Kuro and GCD and XOR and SUM 题目大意:有两种操作:①给一个数v,加入数组a中②给出三个数x,k,s:从当前数组a中找出一个数u满足 u ...

随机推荐

  1. 【C++】《C++ Primer 》第八章

    第八章 IO库 一.IO类 1. 标准库定义的IO类型 头文件 作用 类型 iostream 从标准流中读写数据 istream, wistream 从流读取数据 ostream, wostream ...

  2. Manjaro Linux 5.9.11-3安装和配置全局截图工具FlameShot教程

    背景说明 截图工具是日常适用频率较高的一种系统工具,在Linux下也有不少常用截图工具,如deepin-screenshot等,但是今天我们要介绍的是FlameShot--一款更加精致的Linux全局 ...

  3. innodb日志文件大小

    innodb是用多个文件作为一组循环日志,通常不需要修改默认的日志数量,只修改每个日志文件的大小即可,要修改日志文件大小,需要完全关闭mysql,将旧的日志文件移到其他地方保存,重新配置参数,然后重启 ...

  4. /etc/hosts文件

    这个文件告诉主机哪些域名对应哪些ip,哪些主机名对应哪些ip. 一般也三个域 网络ip地址 主机名或域名 主机名别名 两部分的时候 主机ip地址和主机名

  5. python sqlite3增加表字段

    给sqlite3表格增加新字段,要注意大小写,要不然不成功. 一开始这样写,不成功! 后面规范写,按大小写严格规范写! 成功了!现在查看新增加的字段commit: 仔细看,这下全部小写,括表名称.co ...

  6. ctfhub技能树—sql注入—整数型注入

    打开靶机 查看页面信息 查看回显位 查询数据库名 查询表名 查询字段 查询字段信息 使用sqlmap食用效果更佳 查数据库名 python2 sqlmap.py -u http://challenge ...

  7. 中断与系统调用深度分析(以网络编程接口SocketAPI为例)

    1.从计算机CPU与I/O设备的交互方式谈起 计算机CPU与I/O设备的交互方式有最早的程序查询(也叫轮询)方式,发展到后来的程序中断方式,DMA方式等.简单来说,最早的程序查询方式的机制是,CPU若 ...

  8. SpringBoot单元测试的两种形式

    @ 目录 前言 demo环境 springbootTest Junit 总结 前言 最近公司要求2021年所有的项目代码单元测试覆盖率要达到90%,作为刚毕业的小白来说这简直就是噩梦啊,springb ...

  9. 让源码包apache服务被服务管理命令识别

    在默认情况下,源码包服务是不能被系统的服务管理命令所识别和管理的,但是如果我们做一些设定,则也是可以让源码包服务被系统的服务管理命令所识别和管理的.不过笔者并不推荐大家这样做, 因为这会让本来区别很明 ...

  10. C++旋转数组(三种解法详解)

    题目描述 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 附加要求 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题. 你可以使用空间复杂度为 O(1) 的 原地 ...