删边转化为加边

然后每次用线段树合并就行.....

确确实实很简单

然而为什么线段树合并跑不过$splay$的启发式合并,常数稍大了点...

复杂度$O(n \log n)$

#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
#define ri register int
#define ll long long
#define tpr template <typename ra>
#define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
#define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)
#define gc getchar
inline int read() {
int p = , w = ; char c = gc();
while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
while(c >= '' && c <= '') p = p * + c - '', c = gc();
return p * w;
}
int wr[], rw;
#define pc(iw) putchar(iw)
tpr inline void write(ra o, char c = '\n') {
if(!o) pc('');
if(o < ) o = -o, pc('-');
while(o) wr[++ rw] = o % , o /= ;
while(rw) pc(wr[rw --] + '');
pc(c);
}
}
using namespace std;
using namespace remoon; #define sid 200050
#define pid 5000500 ll ans;
ll sum[sid];
int n, id, cnp;
int x[sid], y[sid], p[sid];
int cap[sid], nxt[sid], node[sid], val[sid], s[sid];
int fa[sid], rt[sid], ls[pid], rs[pid], sz[pid]; inline void addedge(int u, int v, int w) {
nxt[++ cnp] = cap[u]; cap[u] = cnp;
node[cnp] = v; val[cnp] = w;
nxt[++ cnp] = cap[v]; cap[v] = cnp;
node[cnp] = u; val[cnp] = w;
} inline int find(int o) {
if(fa[o] == o) return o;
return fa[o] = find(fa[o]);
} inline void insert(int &now, int l, int r, int v) {
now = ++ id; sz[now] = ;
if(l == r) return;
int mid = (l + r) >> ;
if(v <= mid) insert(ls[now], l, mid, v);
else insert(rs[now], mid + , r, v);
} inline int merge(int x, int y, int l = , int r = << ) {
if(!x || !y) return x + y;
if(l == r) ans += 1ll * sz[x] * sz[y];
int mid = (l + r) >> ;
ls[x] = merge(ls[x], ls[y], l, mid);
rs[x] = merge(rs[x], rs[y], mid + , r);
sz[x] += sz[y];
return x;
} #define cur node[i]
inline void dfs(int o, int f) {
insert(rt[o], , << , s[o]);
for(int i = cap[o]; i; i = nxt[i])
if(cur != f) s[cur] = s[o] ^ val[i], dfs(cur, o);
} int main() {
n = read();
rep(i, , n - ) {
x[i] = read(); y[i] = read();
int w = read(); addedge(x[i], y[i], w);
}
rep(i, , n) fa[i] = i;
rep(i, , n - ) p[i] = read();
dfs(, );
drep(i, n - , ) {
int u = find(x[p[i]]), v = find(y[p[i]]);
fa[v] = u; merge(rt[u], rt[v]);
sum[i] = ans;
}
rep(i, , n) write(sum[i]);
return ;
}

luoguP3359 改造异或树 线段树合并的更多相关文章

  1. 浅谈树套树(线段树套平衡树)&学习笔记

    0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...

  2. HDU 5649 DZY Loves Sorting(二分答案+线段树/线段树合并+线段树分割)

    题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \le ...

  3. [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)

    解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...

  4. 权值线段树&线段树合并

    权值线段树 所谓权值线段树,就是一种维护值而非下标的线段树,我个人倾向于称呼它为值域线段树. 举个栗子:对于一个给定的数组,普通线段树可以维护某个子数组中数的和,而权值线段树可以维护某个区间内数组元素 ...

  5. BZOJ 3439 Kpm的MC密码 (Trie树+线段树合并)

    题面 先把每个串反着插进$Trie$树 每个节点的子树内,可能有一些节点是某些字符串的开头 每个节点挂一棵权值线段树,记录这些节点对应的原来字符串的编号 查询的时候在线段树上二分即可 为了节省空间,使 ...

  6. LG4556 [Vani有约会]雨天的尾巴 动态开点线段树+线段树合并

    问题描述 LG4556 题解 对于每一个结点,建立一棵动态开点线段树. 然后自低向上合并线段树. 同时维护整个值域的最大值和最大值位置. \(\mathrm{Code}\) #include<b ...

  7. UOJ#470. 【ZJOI2019】语言 虚树,线段树合并

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ470.html 前言 做完情报中心来看这个题突然发现两题有相似之处然后就会做了. 题解 首先,我们考虑将所有答案点对分为两 ...

  8. EC Round 33 F. Subtree Minimum Query 主席树/线段树合并

    这题非常好!!! 主席树版本 很简单的题目,给一个按照指定节点的树,树上有点权,你需要回答给定节点的子树中,和其距离不超过k的节点中,权值最小的. 肯定首先一想,按照dfs序列建树,然后按照深度为下标 ...

  9. B -- RE:从零开始的异世界生活 线段树

    http://www.ifrog.cc/acm/problem/1117?contest=1016&no=1 其实我是第一次这样用线段树. 首先把所有出现过的数字全部离散化.那么数字就是从[1 ...

随机推荐

  1. MySQL 执行SQL脚本 报ERROR 1231 (42000)的解决办法【转】

    今天在source mysqldump 备份文件时,发现导入的过程中报如下的错误: ERROR 1231 (42000): Variable 'time_zone' can't be set to t ...

  2. oracle11g创建修改删除表

    oracle11g创建修改删除表 我的数据库名字: ORCL         密码:123456 1.模式 2.创建表 3.表约束 4.修改表 5.删除表 1.模式 set oracle_sid=OR ...

  3. centos7的防火墙(firewalld)

    Centos7中默认将原来的防火墙iptables升级为了firewalld,firewalld跟iptables比起来至少有两大好处: 1.firewalld可以动态修改单条规则,而不需要像ipta ...

  4. 洛谷P1972 HH的项链

    传送门啦 分析: 题目描述不说了,大意是,求一段区间内不同元素的种数. 看到区间,我们大概先想到的是暴力(然后炸掉).线段树.树状数组.分块. 下面给出的是一种树状数组的想法. 首先,对于每一段区间里 ...

  5. 记一次对 Laravel-permission 项目的性能优化

    我最近研究分析了在 SWIS上面创建的项目的性能.令人惊讶的是,最耗费性能的方法之一是优秀的  spatie/laravel-permission 包造成的. 经过查阅更多资料和研究,发现一个可能明显 ...

  6. Merkle Tree(默克尔树)算法解析

    Merkle Tree概念 Merkle Tree,通常也被称作Hash Tree,顾名思义,就是存储hash值的一棵树.Merkle树的叶子是数据块(例如,文件或者文件的集合)的hash值.非叶节点 ...

  7. Linux学习笔记之一及虚拟机的安装

    学习Linux基础入门 学习实验楼Linux基础入门--学习笔记系列博客 第一节 Linux系统简介 Linux就是一个操作系统,操作系统在计算机系统中包括系统调用和内核两层.在简单了解了Linux的 ...

  8. 在Eclipse中导入新浪微博SDK

    在Eclipse中导入新浪微博SDK 今天在看<Android开发应用实战>,全书都在讲一个android版的新浪微博客户端怎么做,于是按照书上步骤做.网上有人说这本书没有细节,我想对于小 ...

  9. java通过POI和easypoi实现Excel的导出

    前言 在工作经常会遇到excel导出报表的功能,自己也做过一些,然后在项目里看到同事封装的一个excel导出工具类,着实不错,拿来分享一下.然后,又在网上看到一个使用easypoi实现cxcel导出的 ...

  10. asp.net 微信公众号源码

    需要源码,请加QQ:858-048-581 功能菜单 该源码功能十分的全面,具体介绍如下:1.菜单回复:微信自定义回复.关注时回复.默认回复.文本回复.图文回复.语音回复. 请求回复记录.LBS位置回 ...