Tsinsen-1486:树【Trie树 + 点分治】
暴力部分:
这个题一开始的想法是 n^2 枚举两个点,然后logn维护LCA,在倍增的同时维护异或值和 k 的个数。
s_z_l老爷指导了新的思路,既然这个树只有n^2个LCA,那么枚举LCA,同时向下深搜即可。
标算:
首先点分治,尽力保证树的平衡,然后按照Trie树的性质,贪心,至于k,我们可以把每个节点的值置为like值的最大值,然后在走左右儿子的时候判断一下即可。
点分治时 !vis[E[i].v] && E[i].v != fa 一定不要忘
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define REP(i, a, b) for (int i = a; i < b; i++)
#define drep(i, a, b) for (int i = a; i >= b; i--)
#define travel(x) for (int i = G[x]; i; i = E[i].nx)
#define mp make_pair
#define pb push_back
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second
using namespace std;
typedef long long i64;
typedef pair<int, int> pii;
//********************************
const int maxn = ;
struct Ed {
int u, v, nx; Ed() {}
Ed(int _u, int _v, int _nx) :
u(_u), v(_v), nx(_nx) {}
} E[maxn << ];
int G[maxn], cnt_e;
void addedge(int u, int v) {
E[++cnt_e] = Ed(u, v, G[u]);
G[u] = cnt_e;
}
int vis[maxn];
pii sta[maxn]; int top;
int rt;
int f[maxn], size[maxn], sum;
void getrt(int x, int fa)
{
f[x] = , size[x] = ;
travel(x) {
if (!vis[E[i].v] && E[i].v != fa) {
getrt(E[i].v, x);
size[x] += size[E[i].v];
f[x] = max(f[x], size[E[i].v]);
}
}
f[x] = max(f[x], sum - size[x]);
if (f[x] < f[rt]) rt = x;
}
int read() {
int l = , s(); char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') l = -; ch = getchar(); }
while (ch >= ''&& ch <= '') { s = (s << ) + (s << ) + ch - ''; ch = getchar(); }
return l * s;
}
int trie[][], tab[], rootr;
int ntot;
int n, K;
int c[maxn], w[maxn];
int query(int co, int k) {
int ret();
int p = rootr;
if (tab[p] + k < K) return -;
drep(i, , ) {
int id = co >> i & ;
if (trie[p][id ^ ] && tab[trie[p][id ^ ]] + k >= K) ret |= << i, p = trie[p][id ^ ];
else if (!trie[p][id] || tab[trie[p][id]] + k < K) { ret = -; break; }
else p = trie[p][id];
}
return ret;
}
void insrt(int co, int k) {
int p = rootr;
drep(i, , ) {
tab[p] = max(tab[p], k);
int id = co >> i & ;
if (!trie[p][id]) trie[p][id] = ++ntot;
p = trie[p][id];
}
tab[p] = max(tab[p], k);
}
int ans = -;
void dfs_query(int x, int fa, int co, int k) {
sta[++top] = mp(co, k);
ans = max(ans, query(co, k));
for (int i = G[x]; i; i = E[i].nx) if (!vis[E[i].v] && E[i].v != fa)
dfs_query(E[i].v, x, co ^ w[E[i].v], k + c[E[i].v]);
}
/*
void dfs_insrt(int x, int fa, int co, int k) {
insrt(rootr, co, k, 30);
for (int i = G[x]; i; i = E[i].nx) if (!vis[E[i].v] && E[i].v != fa)
dfs_insrt(E[i].v, x, co ^ w[E[i].v], k + c[E[i].v]);
}
*/
void solve(int x) {
vis[x] = ;
rep(i, , ntot) trie[i][] = trie[i][] = , tab[i] = ;
rootr = ;
ntot = ;
if (c[x] >= K) ans = max(ans, w[x]);
insrt(w[x], c[x]);
travel(x) {
if (vis[E[i].v]) continue;
top = ;
dfs_query(E[i].v, x, w[E[i].v], c[E[i].v]);
rep(j, , top) {
sta[j].xx ^= w[x], sta[j].yy += c[x];
insrt(sta[j].xx, sta[j].yy);
}
}
int tmp = sum;
for (int i = G[x]; i; i = E[i].nx) {
if (!vis[E[i].v]) {
rt = ; sum = size[E[i].v] > size[x] ? tmp - size[x] : size[E[i].v];
getrt(E[i].v, );
solve(rt);
}
}
}
int main() {
n = read(), K = read();
rep(i, , n) c[i] = read();
rep(i, , n) w[i] = read();
REP(i, , n) {
int x, y; x = read(), y = read();
addedge(x, y), addedge(y, x);
}
rt = , sum = n, f[] = n + ;
getrt(, );
solve(rt);
printf("%d\n", ans);
return ;
}
Tsinsen-1486:树【Trie树 + 点分治】的更多相关文章
- Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结
Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...
- 字典树(Trie树)的实现及应用
>>字典树的概念 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.与二叉查找树不同,Trie树的 ...
- [POJ] #1002# 487-3279 : 桶排序/字典树(Trie树)/快速排序
一. 题目 487-3279 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 274040 Accepted: 48891 ...
- 洛谷$P4585\ [FJOI2015]$火星商店问题 线段树+$trie$树
正解:线段树+$trie$树 解题报告: 传送门$QwQ$ $umm$题目有点儿长我先写下题目大意趴$QwQ$,就说有$n$个初始均为空的集合和$m$次操作,每次操作为向某个集合内加入一个数$x$,或 ...
- luoguP6623 [省选联考 2020 A 卷] 树(trie树)
luoguP6623 [省选联考 2020 A 卷] 树(trie树) Luogu 题外话: ...想不出来啥好说的了. 我认识的人基本都切这道题了. 就我只会10分暴力. 我是傻逼. 题解时间 先不 ...
- [转载]字典树(trie树)、后缀树
(1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边 ...
- 字典树 Trie树
什么是Trie树? 形如 其中从根节点到红色节点的路径上的字母所连成的字符串即为一个Trie树上所存的字符串. 比如,这个trie树上有ab,abc,bd,dda这些字符串. 至于怎么构建和查找或添加 ...
- 【HDU - 5790 】Prefix(主席树+Trie树)
BUPT2017 wintertraining(15) #7C 题意 求[min((Z+L)%N,(Z+R)%N)+1,max((Z+L)%N,(Z+R)%N)+1]中不同前缀的个数,Z是上次询问的结 ...
- Luogu P2922 [USACO08DEC]秘密消息Secret Message 字典树 Trie树
本来想找\(01Trie\)的结果找到了一堆字典树水题...算了算了当水个提交量好了. 直接插入模式串,维护一个\(Trie\)树的子树\(sum\)大小,求解每一个文本串匹配时走过的链上匹配数和终点 ...
- 字典树 trie树 学习
一字典树 字典树,又称单词查找树,Trie树,是一种树形结构,哈希表的一个变种 二.性质 根节点不包含字符,除根节点以外的每一个节点都只包含一个字符: 从根节点到某一节点,路径上经过的字符串连接起 ...
随机推荐
- Java类锁和对象锁实践(good)
一.前言 之前对类锁和对象锁是否是互斥的不是太确定,因此决定编写相关的程序进行实践一下.编写前对相关定义约定约定如下: 1. 类锁:在代码中的方法上加了static和synchronized的锁,或者 ...
- java synchronized内置锁的可重入性和分析总结
最近在读<<Java并发编程实践>>,在第二章中线程安全中降到线程锁的重进入(Reentrancy) 当一个线程请求其它的线程已经占有的锁时,请求线程将被阻塞.然而内部锁是可重 ...
- android 学习之RecyclerView
RecyclerView:ListView的升级版,它提供了更好的性能而且更容易使用.该控件是一个可以装载大量的视图集合,并且可以非常效率的进行回收和滚动.当你list中的元素经常动态改变时可以使用R ...
- C++:string类的使用
类 <string> std::string String类的定义 , 其也是个模板类 typedef basic_string<char> string; String cl ...
- linux 用户管理维护 清缓存
#echo 1 > /proc/sys/ vm/drop_caches 2013.10.10 其实一直user group一直都没去弄清楚 只是没去归类,@@一种是对用户/组直接修改(同时也更改 ...
- Itext简绍及操作PDF文件
iText简介 iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库.通过iText不仅可以生成PDF或rtf的文档,而且可以将XML.Html文件转 ...
- 主机windwo7+虚拟机centos如何配置虚拟机可以上网,且与主机互ping通
/etc/sysconfig/network-scripts/ifcfg-eth0的配置如下: E=eth0PROTO=static#IPADDR=10.1.1.138IPADDR=192.168.0 ...
- 获取map中的一个value值以及遍历map获得map里所有key、value的值
前言: 1.声明一个map: Map map = new HashMap();2.向map中放值,注意:map是key-value的形式存放的.如: map.put(”sa”,”dd”); 3.从ma ...
- 1209:Catch That Cow(bfs)
题意: 从一个坐标到另一个坐标的移动方式有三种,即:st-1,st+1,2*st.每移动一步时间是一秒. 给出两个坐标,求得从第一坐标到第二座标的最短时间. #include<iostream& ...
- Mac os 10.11 更新ruby
1.装cocoapods,ruby版本忒低->开始更新ruby->开始更新gem,这是一条不归路啊同志们,各种permission denied,各种路径不存在,各种路径没有读写权限,各种 ...