传送门

文章目录

  • 题意:
  • 思路:

题意:

给你一棵树,每个点原本都有一个权值wiw_iwi​,但是你只知道相邻两个点之间的wu⊕wvw_u\oplus w_vwu​⊕wv​,问你有多少种w1,2,...,nw_{1,2,...,n}w1,2,...,n​
n≤1e5,wi<230n\le1e5,w_i<2^{30}n≤1e5,wi​<230

思路:

显然我们如果确定了一个点的权值,那么其他的点都就确定了。
更具体的是,我们可以求出111到其他点之间的w1⊕wxw_1\oplus w_xw1​⊕wx​,其中我们可以假设w1=0w_1=0w1​=0,那么当给w1⊕aw_1\oplus aw1​⊕a时,就相当于将其他w2,3,...,n⊕aw_{2,3,...,n}\oplus aw2,3,...,n​⊕a,所以我们问题就转换成了对于每个区间求合法的aaa使得li≤wi⊕a≤ril_i\le w_i\oplus a\le r_ili​≤wi​⊕a≤ri​,转换一下就是wi⊕[li,ri]w_i\oplus [l_i,r_i]wi​⊕[li​,ri​]的合法区间。这个区间肯定不是连续的,所以考虑将其拆分成若干区间。
由于拆分的区间肯定不能很多,所以考虑用二进制来拆分这个区间。考虑这样一种形式的二进制区间[xxxx0000,xxxx1111][xxxx0000,xxxx1111][xxxx0000,xxxx1111],其中xxx表示可以是任意数,但是两个的xxx对应位置必须相同。这样的区间满足其异或上wiw_iwi​仍是一段连续的区间。我们惊奇的发现,这个区间后半部分不正是线段树的每段区间吗?所以考虑建一棵[0,230−1][0,2^{30}-1][0,230−1]的线段树,将这个区间插入,可知最多能被分成lognlognlogn段区间。当这个区间被完全包含的时候,我们打一个懒标记即可。
查询的时候如果懒标记=n=n=n的时候,就直接返回区间长度即可。

// Problem: Tree Xor
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/11255/E
// Memory Limit: 524288 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<random>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=5000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n,w[N],p[N];
int l[N],r[N],idx;
struct Node {int l,r;int cnt,lazy;
}tr[N<<2];
vector<PII>v[N];void dfs(int u,int fa) {for(auto x:v[u]) {if(x.X==fa) continue;w[x.X]=w[u]^x.Y;dfs(x.X,u);}
}int newnode() {int u=++idx;tr[u].l=tr[u].r=0;tr[u].cnt=tr[u].lazy=0;return u;
}void insert(int &u,int l,int r,int ql,int qr,int w,int dep) {if(!u) u=newnode();int nl=(l^w)&(((1<<30)-1)^((1<<(dep+1))-1));int nr=(l^w)|((1<<(dep+1))-1);if(nl>=ql&&nr<=qr) {tr[u].lazy++;tr[u].cnt++;return;}if(tr[u].cnt) {if(!tr[u].l) tr[u].l=newnode();if(!tr[u].r) tr[u].r=newnode();tr[tr[u].l].cnt+=tr[u].cnt; tr[tr[u].r].cnt+=tr[u].cnt;tr[u].cnt=0;}int mid=(l+r)>>1;int ll=(l^w)&(((1<<30)-1)^((1<<(dep))-1)),lr=(l^w)|((1<<(dep))-1);int rl=(r^w)&(((1<<30)-1)^((1<<(dep))-1)),rr=(r^w)|((1<<(dep))-1);if(w>>dep&1) {if(ql<=rr) insert(tr[u].r,mid+1,r,ql,qr,w,dep-1);if(qr>=ll) insert(tr[u].l,l,mid,ql,qr,w,dep-1);} else {if(ql<=lr) insert(tr[u].l,l,mid,ql,qr,w,dep-1);if(qr>=rl) insert(tr[u].r,mid+1,r,ql,qr,w,dep-1);}
}int query(int u,int l,int r) {if(!u) return 0;if(tr[u].cnt==n) return r-l+1;if(tr[u].cnt) {if(tr[u].l) tr[tr[u].l].cnt+=tr[u].cnt;if(tr[u].r) tr[tr[u].r].cnt+=tr[u].cnt;tr[u].cnt=0;}int ans=0,mid=(l+r)>>1;ans+=query(tr[u].l,l,mid);ans+=query(tr[u].r,mid+1,r);return ans;
}int main()
{//  ios::sync_with_stdio(false);
//  cin.tie(0);scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d%d",&l[i],&r[i]);for(int i=1;i<=n-1;i++) {int a,b,c; scanf("%d%d%d",&a,&b,&c);v[a].pb({b,c}); v[b].pb({a,c});}dfs(1,0); int rt=newnode();int limit=(1<<30)-1;for(int i=1;i<=n;i++) {insert(rt,0,limit,l[i],r[i],w[i],29);}printf("%d\n",query(1,0,limit));return 0;
}
/**/

2021牛客暑期多校训练营4 E - Tree Xor 线段树 + 拆分区间相关推荐

  1. 2021牛客暑期多校训练营7 xay loves monotonicity 线段树区间合并

    传送门 文章目录 题意: 思路: 题意: 题面挺绕口的,还是看原题比较好. 大概的意思就是让你从给定的区间中选择一个以左端点为起点的一个上升子序列,让后将这些下标存下来,在bbb中将这些位置拿出来后, ...

  2. 2021牛客暑期多校训练营4 D-Rebuild Tree(prufer序列+树形dp)

    D-Rebuild Tree Prufer 是这样建立的:每次选择一个编号最小的叶结点并删掉它,然后在序列中记录下它连接到的那个结点.重复n−2n-2n−2次后就只剩下两个结点,算法结束.(为什么不是 ...

  3. 【2021牛客暑期多校训练营4】Average (二分答案,区间/子数组最大平均值,)

    J Average 题意: 给出长为n,m的序列ai和bi,定义nm的矩阵wij=ai+bj,求一个大小>=xy的子矩阵的平均值最大. 思路: 因为n的范围为1e5,直接n*m计算出wij就已经 ...

  4. 2021牛客暑期多校训练营9

    2021牛客暑期多校训练营9 题号 题目 知识点 A A Math Challenge B Best Subgraph C Cells D Divide-and-conquer on Tree E E ...

  5. 2021牛客暑期多校训练营5

    2021牛客暑期多校训练营5 题号 题目 知识点 A Away from College B Boxes 概率 C Cheating and Stealing D Double Strings 线性d ...

  6. 2021牛客暑期多校训练营4

    2021牛客暑期多校训练营4 题号 题目 知识点 A Course B Sample Game C LCS D Rebuild Tree E Tree Xor 思维+线段树 F Just a joke ...

  7. 2021牛客暑期多校训练营3

    2021牛客暑期多校训练营3 题号 题目 知识点 A Guess and lies B Black and white C Minimum grid 二分图匹配 D Count E Math 数论+打 ...

  8. 2021牛客暑期多校训练营2

    2021牛客暑期多校训练营2 题号 题目 知识点 A Arithmetic Progression B Cannon C Draw Grids D Er Ba Game E Gas Station F ...

  9. 2021牛客暑期多校训练营1

    2021牛客暑期多校训练营1 题号 题目 知识点 难度 A Alice and Bob 博弈论 B Ball Dropping 计算几何 签到 C Cut the Tree D Determine t ...

最新文章

  1. RHEL7系统管理之内核管理
  2. OP07高级电路图-摘自:Reza Moghim
  3. 工控交换机和工业级交换机是怎么区别的,具体有哪些区别?分别应用在什么领域?
  4. diff算法_详解 React 16 的 Diff 策略
  5. [学习OpenCV攻略][001][Ubuntu安装及配置]
  6. [spark]Spark2.4.6用put写入写入Hbase1.3.1
  7. java jxta_java现在还支不支持jxta,怎么官方都没下载了?
  8. DCMTK相关资料汇总
  9. 【音频处理】之 Matlab 实现信号的时域和频域的滤波
  10. Delphi 制作股票分时图
  11. 复现awvs——CVE-2020-1938(CNVD-2020-10487)tomcat ajp 文件包含漏洞
  12. Xmarks被GFW屏蔽后,怎么同步?
  13. matlab cftool光滑曲线导出为什么就不光滑了_不会吧,还有人不知道MATLAB这8个小技巧?...
  14. console的基础使用
  15. 设计模式学习(二)——创建型模式之“工厂模式“
  16. 建模 渲染 计算机配置,设计师专用电脑 8000元i5-7500独显专业渲染建模电脑配置推荐...
  17. 我的博客 http://aofengblog.blog.163.com/
  18. Android计算器(计算表达式,能计算小数点以及括号)方法简单易懂
  19. mysql高德地图设计_基于高德开放平台Map Lab的数据可视化
  20. c++游戏服务器框架

热门文章

  1. linux下python版本升级,linux下升级python版本
  2. 博导眼里本科生的科研能力:“他们还在玩泥巴”
  3. 因为没钱买衣服,我女朋友不要我了......
  4. 为什么中国天才都往美国跑,可美国人的数学那么槽糕
  5. 82 个代码案例实践,带你学好 Python 机器学习
  6. hbase shell 查看列名_hbase shell 常用命令
  7. oss多线程 上传_oss-android/ios-sdk 断点续传(多线程)
  8. mybatis 多租户saas_MybatisPlus 多租户架构(SaaS)实现
  9. 正弦波 程序 角度传感器_激光位移传感器的原理及应用领域
  10. python docx 字体大小_聊聊python办公自动化之Word(上)