[luogu3359]改造异或树
[luogu3359]改造异或树
luogu
和之前某道题类似只有删边的话考虑倒着加边
但是怎么统计答案呢?
我们考虑以任意点为根dfs一遍求出每个点到根的路径异或和s[i]
这样任意两点x,y的路径异或和可以表示成s[x] xor s[y]
那么设当前连的边的边权为w,我们要找出被连通的两个连通块中s[x] xor s[y]=w的(x,y)个数
考虑启发式合并,枚举size小的一边,另一边在map上查,然后把size小的map并到大的中去
#define ll long long
#include<bits/stdc++.h>
using namespace std;
const int _=1e5+5;
int re(){
int x=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
}
int n,cnt;
ll sum,ans[_];
map<int,ll>M[_];
map<int,ll>::iterator it;
int h[_],s[_],fa[_],a[_],b[_],c[_],p[_];
struct edge{int to,next,w;}e[_<<1];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void link(int u,int v,int w){
e[++cnt]=(edge){v,h[u],w};h[u]=cnt;
e[++cnt]=(edge){u,h[v],w};h[v]=cnt;
}
void dfs(int u,int fa){
for(int i=h[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa)continue;
s[v]=s[u]^e[i].w;
dfs(v,u);
}
}
int main(){
n=re();
for(int i=1;i<n;i++){
a[i]=re(),b[i]=re(),c[i]=re();
link(a[i],b[i],c[i]);
}
for(int i=1;i<n;i++)
p[i]=re();
dfs(1,0);
for(int i=1;i<=n;i++)fa[i]=i,M[i][s[i]]=1;
for(int i=n-1;i>=1;i--){
int x=find(a[p[i]]),y=find(b[p[i]]);
if(M[x].size()<M[y].size())swap(x,y);
fa[y]=x;
for(it=M[y].begin();it!=M[y].end();++it)
sum+=1ll*M[x][(*it).first]*(*it).second;
for(it=M[y].begin();it!=M[y].end();++it)
M[x][(*it).first]+=(*it).second;
ans[i]=sum;
}
for(int i=1;i<=n;i++)printf("%lld\n",ans[i]);
return 0;
}
[luogu3359]改造异或树的更多相关文章
- 洛谷 P3359 改造异或树
题目描述 给定一棵n 个点的树,每条边上都有一个权值.现在按顺序删掉所有的n-1条边,每删掉一条边询问当前有多少条路径满足路径上所有边权值异或和为0. 输入输出格式 输入格式: 第一行一个整数n. 接 ...
- luoguP3359 改造异或树 线段树合并
删边转化为加边 然后每次用线段树合并就行..... 确确实实很简单 然而为什么线段树合并跑不过$splay$的启发式合并,常数稍大了点... 复杂度$O(n \log n)$ #include < ...
- luoguP3359 改造异或树
https://www.luogu.org/problemnew/show/P3359 因为 a ^ b ^ b = a,所以我们预处理 1 到所有点的距离,将删边的操作反过来变成加边,对于每一个联通 ...
- HDU 4825 Trie树 异或树!
Xor Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Total S ...
- BZOJ 4017 小 Q 的无敌异或 ( 树状数组、区间异或和、区间异或和之和、按位计贡献思想 )
题目链接 题意 : 中文题 分析 : 首先引入两篇写的很好的题解 题解一.题解二 听说这种和异或相关区间求和的问题都尽量按位考虑 首先第一问.按二进制位计贡献的话.那么对于第 k 位而言 其贡献 = ...
- HUST——1106xor的难题之二(异或树状数组单点修改和区间查询)
1106: xor的难题之二 时间限制: 2 Sec 内存限制: 128 MB 提交: 8 解决: 3 题目描述 上次Alex学长的问题xor难题很简单吧,现在hkhv学长有个问题想问你们. 他现 ...
- BootStrap-DualListBox怎样改造成为双树
BootStrap-DualListBox能够实现将所选择的列表项显示到右边,未选的列表项显示到左边. 但是左右两边的下拉框中都是单级列表.如果要实现将两边都是树(缩进树),选择某个节点时,其子节点也 ...
- 线段树+RMQ问题第二弹
线段树+RMQ问题第二弹 上篇文章讲到了基于Sparse Table 解决 RMQ 问题,不知道大家还有没有印象,今天我们会从线段树的方法对 RMQ 问题再一次讨论. 正式介绍今天解决 RMQ 问题的 ...
- Mysql索引数据结构为什么是B+树?
目录 Mysql索引数据结构 二叉树 红黑树 B-Tree B+Tree Mysql索引数据结构 下面列举了常见的数据结构 二叉树 红黑树 Hash表 B-Tree(B树) Select * from ...
随机推荐
- Java虚拟机内存分配和回收策略
1 对象优先分配在Eden区 对象优先在Eden进行分配,大多数情况下,对象在新生代Eden区进行分配.当Eden区没有足够的空间进行分配时,虚拟机会发起一次Minor GC. 新生代GC(Ninor ...
- 2017.4.18 linux中执行某文件提示权限不够
因为没有对start.sh文件的执行权限,所以提示权限不够. 加一个执行权限: chmod +x start.sh 可以看到,执行权限已经有了.此时再执行,就ok了.
- 【Android高级】NDK/JNI编程技术基础介绍
作为一个Andoird的Java程序猿,会受到Java语言的局限.由于作为一面门向对象的语言不能像C/C++那样轻易调用与硬件有关的操作.因此JNI就搭建了这样一个桥梁,使Java和C/C++语言之间 ...
- 20160208.CCPP体系具体解释(0018天)
程序片段(01):main.c 内容概要:PointWithOutInit #include <stdio.h> #include <stdlib.h> //01.野指针具体解 ...
- Redis源代码分析(十三)--- redis-benchmark性能測试
今天讲的这个是用来给redis数据库做性能測试的,说到性能測试,感觉这必定是高大上的操作了.redis性能測试.測的究竟是哪方面的性能,怎样測试,通过什么指标反映此次測试的性能好坏呢.以下我通过源代码 ...
- 质量平台建设之Mock平台
转载:http://blog.csdn.net/spark2008/article/details/51372913 基于目前系统越来越多,在项目开发过程中,减少各模块之间的开发依赖,另保证各个系统模 ...
- java学习笔记——可用链表
NO 链表方法名称 描述 1 public void add(数据类型 对象) 向链表中增加数据 2 public int size() 查看链表中数据个数 3 public boolean isEm ...
- Android 完美退出 App 方法
大家都知道 Android 的 Activity 是存着历史栈的,比如从 A -> B -> C,C 完成 finish 后回到 B,把所有的Activity 都 finish了,程序就自 ...
- 微信小程序 - 关于下拉刷新
// 拉取数据 fetchData: function() { wx.request({ url: 'http://v.juhe.cn/toutiao/index', data: { type: '' ...
- hdu 3667 /2010哈尔滨赛区H题 费用与流量为非线性关系/费用流
题意: 在一般费用流题目改动:路过某路,每x单位流量须要花费 ai*x^2(ai为给定的系数). 開始的的时候,一看仅仅只是是最后统计费用上在改动罢了,一看例子.发现根本没那么简单(ps:以后每次写程 ...