题目链接


题目大意:

就是给你nnn个节点的树,树上每个节点都有一个权值wi∈[li,ri]w_i\in[l_i,r_i]wi​∈[li​,ri​],以及相邻(u,v)(u,v)(u,v)的异或值wuXORwvw_uXORw_vwu​XORwv​
问你w1...nw_{1...n}w1...n​有多少种取值?


解题思路:

  1. 我们知道如果一个节点的权值定下来的话,那么整颗树的所有点的权值都定下来了!

  2. 现在我们假设w1′=0w'_1=0w1′​=0那么我们就可以解出w2....n′w'_{2....n}w2....n′​我们设这个为初始解

  3. 如果w1′=aw'_1=aw1′​=a的话就相当与w2...n′XORaw'_{2...n}XORaw2...n′​XORa

  4. 那么就是有nnn组限制
    li≤wiXORa≤ri∣i∈[1,n]l_i\leq w_iXORa\leq r_i|i\in[1,n]li​≤wi​XORa≤ri​∣i∈[1,n]
    求满足上面式子aaa的个数
    那么
    wiXORli≤a≤wiXORri∣i∈[1,n]w_iXORl_i\leq a \leq w_iXORr_i|i\in[1,n]wi​XORli​≤a≤wi​XORri​∣i∈[1,n]
    但是根据异或的性质这些区间是不连续的
    那么就是求
    [wi(XOR)li,wi(XOR)ri]∣i∈[1,n][w_i(XOR)l_i , w_i(XOR)r_i]|i\in[1,n][wi​(XOR)li​,wi​(XOR)ri​]∣i∈[1,n]
    里面连续的区间
    然后对这nnn组区间求交就是答案了!!

  5. 但是如何求呢?
    我们知道对于[8,15]10[8,15]_{10}[8,15]10​−>->−>[1000,1111]2[1000,1111]_2[1000,1111]2​
    里面除了高位之外下面的低3位的组合是全部的组合!
    就是000,001,010,....110,111000,001,010,....110,111000,001,010,....110,111都是有的,那么就是你任何一个数异或上这个区间里面的数,你低3位的取值是全部的!那么你只看高位,低3位全部变成0,就是这个区间里面的最小值,然后低3位全是1就是最大值!!

那么这个区间怎么划分呢?
巧了和线段树有关
[0,1,2,3,4,5,6,7]10[0,1,2,3,4,5,6,7]_{10}[0,1,2,3,4,5,6,7]10​
[000,001,....,110,111]2[000,001,....,110,111]_2[000,001,....,110,111]2​
那么区间划分除2
[0,1,2,3][4,5,6,7][0,1,2,3] [4,5,6,7][0,1,2,3][4,5,6,7]
[000,001,010,011]2[100,101,110,111]2[000,001,010,011]_2[100,101,110,111]_2[000,001,010,011]2​[100,101,110,111]2​这时候就是低2位了!!
每次划分一次低位就减一!!

#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 9;
const int maxn = 500010;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x)
{x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args)
{read(first);read(args...);
}
int n;
int L[maxn], R[maxn];
vector<PII> G[maxn];
int val[maxn];
vector<PII> vec;
inline void dfs(int u, int fa, int Xor) {val[u] = Xor;for(auto it : G[u]) {int v = it.first, w = it.second;if(v == fa) continue;dfs(v,u,Xor^w);}
}inline void query(int L, int R, int val, int l, int r, int pos) {if(L <= l && R >= r) {//把低pos位设置成0int ql = (l ^ val) & (((1 << 30) - 1) ^ ((1 << pos) - 1));int qr = ql + (1 << pos) - 1;//设置成1vec.push_back({ql,qr});return;} if(L <= mid) query(L,R,val,l,mid,pos-1);if(R > mid) query(L,R,val,mid+1,r,pos-1);
}inline int slove() {//差分求区间交!!vector<PII> res;for(auto it : vec) {res.push_back({it.first,1});res.push_back({it.second+1,-1});}sort(res.begin(),res.end());int tag = 0;int ans = 0;int last;for(auto it : res) {if(tag == n) ans += it.first - last;tag += it.second;last = it.first;}return ans;
}int main() {IOS;int T;//  cin >> T;T = 1;while(T --) {cin >> n;for(int i = 1; i <= n; ++ i) cin >> L[i] >> R[i];for(int i = 1; i <= n - 1; ++ i) {int u, v , val;cin >> u >> v >> val;G[u].push_back({v,val});G[v].push_back({u,val});}dfs(1,-1,0);for(int i = 1; i <= n; ++ i) query(L[i],R[i],val[i],0,(1 << 30)-1,30);cout << slove();}
}

线段树 ---- 牛客多校4 ETree Xor 区间异或分段相关推荐

  1. 线段树 ---- 牛客多校2021多校第6场 H Hopping Rabbit 扫描线

    思维误区:扫描线 扫描线模板里面有两个变量一个是cover和lengthcover和lengthcover和length covercovercover是标记下面是否覆盖满了,但是covercover ...

  2. 2021牛客多校#4 E-Tree Xor

    文章目录 题目链接 题目大意 题解 参考代码 题目链接 传送门 题目大意 给定一棵n(1≤n≤105)n(1 \leq n \leq 10^5)n(1≤n≤105)的节点的树,第iii个节点的权值为W ...

  3. 2021牛客多校4 - Tree Xor(线段树+异或区间拆分)

    题目链接:点击查看 题目大意:给出一棵 nnn 个点组成的树,每个点权的取值范围是 [li,ri][l_i,r_i][li​,ri​],每条边权代表的是两点的异或值,现在问这棵树有多少种有效赋值 题目 ...

  4. 带 sin, cos 的线段树 - 牛客

    链接:https://www.nowcoder.com/acm/contest/160/D 来源:牛客网 题目描述 给出一个长度为n的整数序列a1,a2,...,an,进行m次操作,操作分为两类. 操 ...

  5. Splay ---- 2018牛客多校第三场 区间翻转搞区间位移 或者 rope可持久化块状链表

    题目链接 题目大意: 就是每次把牌堆中若干个连续的牌放到堆顶,问你最后牌的序列. 解题思路: Splay 区间翻转的模板题: 对于一个区间[1,2,3,4,5,6,7,8][1,2,3,4,5,6,7 ...

  6. 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数

    目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...

  7. 2019牛客多校训练第十场F Popping Balloons

    2019牛客多校训练第十场F Popping Balloons 题意:二维平面内给你若干个点,然后你可以在x轴和y轴分别射三枪(每一枪的间隔是R),问最多能射掉多少气球. 题解:贪心.这个应该只能算作 ...

  8. python字符串去重及排序 牛客_2018牛客多校第一场 D.Two Graphs

    题意: n个点,m1条边的图E1,n个点,m2条边的图E2.求图E2有多少子图跟图E1同构. 题解: 用STL的全排列函数next_permutation()枚举映射.对于每一种映射枚举每一条边判断合 ...

  9. 2020 牛客多校第一场

    2020 牛客多校第一场 A. B-Suffix Array 后缀数组的思想:倍增+桶排序的方式找出一串连续序列后缀的大小.虽说正常使用的时候都是字典序,但是只要修改排序方式,也能够达到一个类似的&q ...

最新文章

  1. 高性能MySQL之架构与历史(1)
  2. 【呆鸟译Py】20个数据分析前必须搞清楚的问题
  3. 学习scala的网站汇总
  4. 软件需求说明书 概要设计说明书 项目开发计划 详细设计说明书 模版
  5. How is new Appoinment id generated in my task followup scenario
  6. (转)CentOS分区操作详解
  7. python去重且顺序不变_Python实现嵌套列表去重方法示例
  8. 云计算实战系列三(Linux文件管理)
  9. Building Apps for Windows Phone 8.1教程下载地址整理
  10. 云计算设计模式(二十四)——仆人键模式
  11. ServletContextListener 启动SPRING加载数据到缓存的应用
  12. python爬取教务系统_python 爬取 强智科技教务系统(湖南)
  13. Linux 任务控制的几个技巧( , [ctrl]-z, jobs, fg, bg, kill)
  14. nvme分区选mbr还是guid_[Win] 最强大的磁盘分区工具 DiskGenius v5.1.1 中文专业破解版...
  15. 直方图规定化计算过程
  16. 能源DEA--对于业务和环境评估的规模报酬与规模损害
  17. 如何画一个对话气泡框(css实现)
  18. 电桥的原理,及非线性误差
  19. 爱因斯坦:三篇著名演讲
  20. 前端体系必备的软技能和知识点

热门文章

  1. DEV为什么不能输出小数 浮点数?
  2. 什么是近似算法?它适用于哪些问题?这篇文章给你答案
  3. 计算机视觉知识点总结
  4. Redis的数据结构及应用场景
  5. CPU对指令长度的判断
  6. 关于软件开发你真正需要知道的几个事情
  7. 我国企业大数据的发展与应用总览
  8. STL (13) 非变动型算法
  9. Tomcat 源码阅读记录(1)
  10. 《zabbix用户权限分配管理》-8