Tree Xor

题意:

一颗有n个点的树,边权给出,第i个节点的权值为Wi,但并不知道Wi,只知道Wi在[Li,Ri],边权等于两端点的异或值
问W序列有多少可能

题解:

如果我们知道一个点的值,就可以推出其他所有点的值。
现在我们令w[1]=0,解出剩下的w,如果令w[1] = a ,剩下的w都会xor上a
所以就变成了求解合法的a的数量,限制有n个不等式,形式为:
L[i] <= W[i] Xor a <= R[i]
你可能会觉得a会属于[L[i] Xor W[i],R[i] Xor w[i]],但问题是原本[L,R]是连续的,但是异或w[i]后不一定连续。
出题很妙的地方:

我们利用[0,230-1]的线段树,把[L[i],R[i]]分成O(logW)个连续的区间,且每个区间的形式是K…30位相同,0…k-1位是0到2k-1,这样的区间异或上w[i]后仍然还是一个区间

刚才这一部分是官方题解里的,谈谈我的理解
刚才说了区间xor W[i]后不一定连续,但是如果我们把区间[L[i],R[i]]分成好几个小区间,这个小区间Xor W[i]后,这几个小区间可能本身还是连续的(不看这几个小区间之间的联系,只看小区间本身)。
那该怎么分呢?我们利用[0,230-1]的线段树,我们想下建树过程,一开始是[L=0,R=111111…(一共30个1)],然后分治建边,分成两个区间[L=0,R=1111…(一共29个)],[L=1000…(一共29个0),R=11111…(一共30个1)],一直这样下去,得到的区间都满足下面形式:
[xxxx0000,xxxx1111],xxxx部分是相同的,也就是前k位相同,后k位分别是0和1
这样的区间异或上一个数x后仍然还是一个连续完整区间(很神奇,可以自己测试以下)
我用L=80(101000),R=95(1011111),当x小于等于15(1111)时,[L,R]的区间还是本区间只是内部打乱顺序,当大于15时[L,R]区间会整体变小,但是区间长度依旧不变。我认为是一位这个区间的对称的,所以才会这样
这样就可以将原区间[L[i],R[i]]拆成n组区间,a属于这个n组区间,那n组区间求个交(可以利用差分),就得到a的数量

代码:

#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <iomanip>
#include <map>
#include <cstdio>
#include <stack>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define endl '\n'
ll gcd(ll a, ll b){return b == 0 ? a : gcd(b, a % b);
}
void input(){freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
}
inline int read(){int x=0,f=1;char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*f;
}
const int N = 1e6+10, M = N * 2, inf = 1e8;
int n, L[N], R[N], W[N];
vector<pii> G[N];
vector<pii> seg, v;
// l r 是当前点限制的左右取值范围
// vl vr 是当前这段区间所代表的取值范围
// dep 表示深度,v是在w1取0的条件下当前点的取值
void build(int l, int r, int vl, int vr, int dep, int v){if(l <= vl && vr <= r){int nowl = (vl ^ v) & (((1<<30)-1) ^ ((1<<dep) - 1));int nowr = nowl + (1<<dep) - 1;//cout<<"vl="<<vl<<" "<<"vr="<<vr<<endl;//cout<<"nowl="<<nowl<<" "<<"nowr="<<nowr<<endl; seg.push_back({nowl, nowr});}else{int mid = (vl + vr) >> 1;if(l <= mid) build(l, r, vl, mid, dep-1, v);if(r > mid) build(l, r, mid+1, vr, dep-1, v);}
}
// 使用dfs求解每个点的值
void dfs(int x, int fa, int val){if(x != 1) build(L[x], R[x], 0, (1<<30)-1, 30, val);for(auto i : G[x]){if(i.first == fa) continue;dfs(i.first, x, i.second^val);}
}
int main(){ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin>>n;for(int i = 1; i <= n; i++) cin>>L[i]>>R[i];for(int i = 1; i < n; i++){int u, v, w; cin>>u>>v>>w;G[u].push_back({v, w});G[v].push_back({u, w});}dfs(1, -1, 0);seg.push_back({L[1], R[1]});for(auto i : seg) v.push_back({i.first, 1}), v.push_back({i.second + 1, -1});//差分思想 sort(v.begin(), v.end());int res = 0, sum = 0;for(int i = 0; i < (int)v.size(); i++){sum += v[i].second;if(sum == n) //当存在n个区间同时满足时,就是a的取值范围 res += v[i+1].first - v[i].first;}cout<<res<<endl;return 0;
}

Tree Xor(未完全搞定)相关推荐

  1. android 软件盘未弹出如何获取高度,Android 软键盘的那些坑,一招搞定!

    3 软键盘高度获取 对于上面的问题1,既然想要EditText单独顶上去,那么就需要知道当前键盘弹出的高度,再设置EditText坐标即可. 问题的关键转变为如何获取键盘的高度. Activity窗口 ...

  2. 手机密码锁机的朋友不用再去营业厅解锁.自己搞定(未测试)

    (注意:本文为网上收集,仅仅为个人收藏,如果强行使用造成严重后果本人不负任何责任! 强烈建议:锁了机还是拿到营业厅解锁) 手机密码锁机的朋友不用再去营业厅解锁.自己搞定 解话机锁:*2767*2878 ...

  3. 一小时搞定计算机网络面试

    一小时搞定计算机网络面试 一.计算机网络体系结构参考模型: 七层协议的作用: 1.物理层:主要定义物理设备标准,如网线的接口类型.光纤的接口类型.各种传输介 质的传输速率等.它的主要作用是传输比特流( ...

  4. 60分钟搞定,基于ResNet和Azure GPU加速的肺癌CT图像识别

    用深度学习技术分析医学影像和视频是一个新的研究方向.通过已训练好的卷积神经网络,能很快地搭建并训练自己的深度学习系统. 本文介绍了微软的一个比赛队伍参加2017年Kaggle肺癌CT图像检测比赛,成功 ...

  5. (一次性搞定)ORB_SLAM2地图保存与加载

    (一次性搞定)ORB_SLAM2地图保存与加载 本文记录了ORB_SLAM2中地图保存与加载的过程. 参考博客: https://blog.csdn.net/qq_34254510/article/d ...

  6. 自定义html托管,10分钟搞定“傻瓜式”的静态网站搭建托管之旅

    原文发布于微信公众号:腾讯云存储(关注有惊喜) 静态网站:有别于动态网站,它就是只包含静态内容(如图片.音频.视频.HTML.CSS.JS)的网站,不依赖服务器端动态渲染页面. 那么静态网站托管应该如 ...

  7. [喵咪的Liunx(1)]计划任务队列脚本后台进程Supervisor帮你搞定

    喵咪的Liunx(1)]计划任务队列脚本后台进程Supervisor帮你搞定 前言 哈喽大家好啊,好久不见啊(都快一个月了),要问为什么没有更新博客呢只应为最近在录制PhalApi的视频教程时间比较少 ...

  8. 机器学习建模神器PyCaret已开源!提升效率,几行代码轻松搞定模型

    Datawhale干货 编译:张峰,Datawhale成员 寄语:PyCaret,是一款 Python中的开源低代码(low-code)机器学习库,支持在「低代码」环境中训练和部署有监督以及无监督的机 ...

  9. 【C语言】一文搞定如何计算结构体的大小----结构体内存对齐规则

    要搞定如何正确地计算一个结构体的大小,我们就要深刻理解结构体内存对齐规则: 结构体内存对齐规则: 1.结构体的第一个成员永远在结构体起始位置偏移量为0的位置: 2.结构体成员从第二个成员开始,总是放在 ...

最新文章

  1. 如何访问自定义键值的二维数组
  2. LumaQQ.NET操作指令制作(3)
  3. 成为优秀高级程序员的10个要点
  4. CSS3笔记之基础篇(一)边框
  5. C语言main()主函数执行完毕后是否会再执行一段代码
  6. P4414 [COCI2006-2007#2] ABC(python3实现)
  7. 如何使用CSS3 Border Radius属性
  8. node-包管理工具 npm
  9. 【Calcite】Calcite 的SQL解析
  10. Leetcode每日一题:376.wiggle-subsequence(摆动的序列)
  11. Mac 设置终端命令快捷方式
  12. 短视频发布之前要注意什么?从配音到发布时间,选对才能吸粉引流
  13. c语言常用逻辑符号,C语言常用逻辑符号.doc
  14. 世界500强企业名称中英对照
  15. 【DZS-12CE/S DC220V型直流回路监视继电器】
  16. 计算机应用专科学年鉴定表,计算机应用技术专业学生大一学年自我鉴定.docx
  17. 鲁大师发布2022半年报手机UI排行榜,vivo OriginOS成为最流畅UI
  18. GTX1650Super和GTX1060哪个好?
  19. MATLAB的水果分级系统
  20. 电源知识——LDO线性电源、开关电源(基础)

热门文章

  1. 东北大姐剪纸被误认为油画,遭人质疑二十多年,只因太过逼真,看完后:真香!不愧是天下第一剪!...
  2. 程序员为啥365天都背电脑包?这答案我服!
  3. 这是一份编程宝典,请查收!
  4. java 中时间计算_java中关于时间的计算
  5. 按照学号查找学生_[源码和文档分享]基于JAVA和MYSQL数据库的学生成绩管理系统...
  6. 80040e14 mysql_【ASP】提示错误80040e14
  7. mysql插入时间区间_mybatis插入数据时返回主键以及MySQL根据时间区间查询问题总结...
  8. 对象中multipartfile 空报错_Python 为什么会有个奇怪的“...”对象?
  9. java中可以用浮点作为循环变量吗_Java千问:Java循环语句的几个冷门知识点你都知道吗?...
  10. java jdbc 删除_java使用jdbc实现各种类型添加删除修改数据