题目:http://www.tsinsen.com/A1486

题解:

其实看到和路径有关的就应该想到点分治。

我们找出重心之后遍历每一棵子树得到它的 { x=经过特殊点的个数,y=到rt的异或和}

然后我们按x排序,维护两个头尾指针不断把满足条件的加入trie,然后把左边的放进trie里查询。

但是还有一个问题,所取的两个点不能位于同一棵子树!!!

我yy了一个做法。我们在用三元组来记录{ x=经过特殊点的个数,y=到rt的异或和,ch=所属子树}

然后往trie里插的时候,每条边保留两个ch表示有哪个子树的点从trie往下经过了这里。必须保证这两个ch不同。

然后查询的时候就判断就行了。注意任何时刻往下走的时候都要判断可行性,否则直接返回-1.

代码:

 #include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 250000+5
#define maxm 8000000+5
#define eps 1e-10
#define ll long long
#define ull unsigned long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
#define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
#define mod 1000000007
#define lch k<<1,l,mid
#define rch k<<1|1,mid+1,r
#define sqr(x) (x)*(x)
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
int n,m,k,cnt,tot,head[maxn],v[maxn],w[maxn],t[maxm][][],s[maxn],f[maxn],sum,rt,ans=-;
bool del[maxn];
struct edge{int go,next;}e[*maxn];
struct rec{int x,y,ch;}a[maxn];
inline bool cmp(rec a,rec b){return a.x<b.x;}
inline void add(int x,int y)
{
e[++tot]=(edge){y,head[x]};head[x]=tot;
e[++tot]=(edge){x,head[y]};head[y]=tot;
}
inline void insert(int y,int ch)
{
int x=;
for3(i,,)
{
int j=y>>i&;
if(!t[x][j][])t[x][j][]=++tot,t[x][j][]=ch;
else if(t[x][j][]!=ch)t[x][j][]=ch;
x=t[x][j][];
}
}
inline int query(int y,int ch)
{
int x=,ret=;
for3(i,,)
{
int j=y>>i&^;
if(t[x][j][]&&((t[x][j][]&&t[x][j][]!=ch)||(t[x][j][]&&t[x][j][]!=ch)))ret^=<<i,x=t[x][j][];
else
{
j^=;
if(t[x][j][]&&((t[x][j][]&&t[x][j][]!=ch)||(t[x][j][]&&t[x][j][]!=ch)))x=t[x][j][];
else return -;
}
}
return ret;
}
inline void getdep(int x,int fa,int w1,int w2,int w3)
{
a[++cnt]=(rec){w1,w2,w3};
for4(i,x)if(!del[y]&&y!=fa)getdep(y,x,w1+v[y],w2^w[y],w3);
}
inline void getrt(int x,int fa)
{
s[x]=;f[x]=;
for4(i,x)if(!del[y]&&y!=fa)
{
getrt(y,x);
s[x]+=s[y];
f[x]=max(f[x],s[y]);
}
f[x]=max(f[x],sum-s[x]);
if(f[x]<f[rt])rt=x;
}
inline void work(int x)
{
del[x]=;cnt=;
for4(i,x)if(!del[y])getdep(y,x,v[x]+v[y],w[x]^w[y],y);
sort(a+,a+cnt+,cmp);
int tmp=k+v[x],j=cnt;
for1(i,cnt)
{
while(j>i&&a[i].x+a[j].x>=tmp)insert(a[j].y,a[j].ch),j--;
ans=max(ans,query(a[i].y^w[x],a[i].ch));
}
for1(i,cnt)if(a[i].x>=k)ans=max(ans,a[i].y);
for0(i,tot)t[i][][]=t[i][][]=t[i][][]=t[i][][]=t[i][][]=t[i][][]=;
tot=;
for4(i,x)if(!del[y])
{
sum=s[y];rt=;
getrt(y,x);
work(rt);
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();k=read();
for1(i,n)v[i]=read();
for1(i,n)w[i]=read();
for1(i,n-)add(read(),read());
tot=;
sum=n;
f[rt=]=inf;
getrt(,);
work(rt);
for1(i,n)if(v[i]>=k)ans=max(ans,w[i]);
cout<<ans<<endl;
return ;
}

A1486. 树(王康宁)的更多相关文章

  1. 【Tsinsen-A1486】树(王康宁) 点分治 + Trie

    A1486. 树(王康宁) 时间限制:1.0s   内存限制:512.0MB   总提交次数:455   AC次数:97   平均分:52.62 查看未格式化的试题   提交   试题讨论 试题来源 ...

  2. Tsinsen A1486. 树(王康宁)

    Description 一棵树,问至少有 \(k\) 个黑点的路径最大异或和. Sol 点分治. 用点分治找重心控制树高就不说了,主要是对答案的统计的地方. 将所有路径按点的个数排序. 可以发现当左端 ...

  3. 搭建Django链接MySQL流程(python2版)

    之前生成选型python3,除了用的python3的pymysql模块之外其他的都是一样的. 1.首先搭建mysql(Mariadb)数据库(单点)         安装方式分为yum安装,rpm包安 ...

  4. 王学长的AAA树

    让我们响应王学长的号召勇敢的分开写splay和lct吧! 分开写大法好!!!!!!!!!!!杜教的ch[4]弱爆了!!!! #include <stdio.h> #include < ...

  5. 「模拟8.18」字符串(卡特兰数)·乌鸦喝水(树状数组,二分)·所驼门王的宝藏(tarjan,拓扑)

    最近好颓啊,所以啥都做不出来 简单说一下这次考试,分机房了,还分不同考卷,果然我还是留在二机房的蒟蒻, 大概也只有这样的简单题,才能勉强水个rank 3吧........ 其实不必管在哪个机房,努力便 ...

  6. 算法与数据结构(十一) 平衡二叉树(AVL树)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

  7. HDU 4417 (划分树+区间小于k统计)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4417 题目大意:给定一个区间,以及一个k值,求该区间内小于等于k值的数的个数.注意区间是从0开始的 ...

  8. EF4.0、4.3创建表达式树状动态查询总结

    ---------------------------------------------快速适用 效果: where name like '%王%' and Age>=35 or Age< ...

  9. Atitti 图像处理 特征提取的科技树 attilax总结

    Atitti 图像处理 特征提取的科技树 attilax总结 理论 数学,信号处理,图像,计算机视觉 图像处理 滤波 图像处理 颜色转换 图像处理 压缩编码 图像处理 增强 图像处理 去模糊 图像处理 ...

随机推荐

  1. 浅谈MySQL索引背后的数据结构及算法【转】

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  2. javascript实现数据结构:线性表--线性链表(链式存储结构)

    上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...

  3. leetcode single number系列

    这个系列一共有三题,第一题是一组数里除了一个数出现一次之外,其他数都是成对出现,求这个数. 第二题是一组数里除了两个数出现一次外,其他数都是成对出现,求这两个数 第三题是一组数里除了一个数出现一次外, ...

  4. C#索引器及示例

    public class IndexSeletor<T> where T:struct { private List<T> _listObj; public IndexSele ...

  5. Simulate a seven-sided die using only five-sided

    问题描述: 如题 转述一下问题,就是说你现在有一个正五面体骰子,然后你怎么用这个正五面体骰子去模拟一个正七面体骰子. 这个问题我接触到几种方法,下面一一阐述. 方法一: rand7()=( rand5 ...

  6. uva 11324

    Problem B: The Largest Clique Given a directed graph G, consider the following transformation. First ...

  7. Java 序列化的高级认识

    序列化 ID 问题 情境:两个客户端 A 和 B 试图通过网络传递对象数据,A 端将对象 C 序列化为二进制数据再传给 B,B 反序列化得到 C. 问题:C 对象的全类路径假设为 com.inout. ...

  8. Java获取最后插入MySQL记录的自增ID值方法

    方法一: String sql = "INSERT INTO users (username,password,email) VALUES (?,?,?);"; PreparedS ...

  9. 2014多校第二场1011 || HDU 4882 ZCC Loves Codefires (贪心)

    题目链接 题意 : 给出n个问题,每个问题有两个参数,一个ei(所要耗费的时间),一个ki(能得到的score).每道问题需要耗费:(当前耗费的时间)*ki,问怎样组合问题的处理顺序可以使得耗费达到最 ...

  10. poj 2311 Cutting Game 博弈论

    思路:求SG函数!! 代码如下: #include<iostream> #include<cstdio> #include<cmath> #include<c ...