[TS-A1486][2013中国国家集训队第二次作业]树[树的重心,点分治]
首先考虑暴力,可以枚举每两个点求lca进行计算,复杂度O(n^3logn),再考虑如果枚举每个点作为lca去枚举这个点的子树中的点复杂度会大幅下降,如果我们将每个点递归考虑,每次计算过这个点就把这个点删掉,那么如果每次删掉的点是当前子树的重心,枚举点对的复杂度就只有O(logn),对于每次查询答案在trie树中找到时间复杂度基本可视为O(1),最后在分治同时考虑“关键点”即可。总复杂度O(nlogn)。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime> using namespace std; struct Edge
{
int to,next;
}e[]; int n,k,Ans=-;
int Size[],cnt,p[],f[],a[];
bool visited[]; void Add_edge(const int x,const int y)
{
e[++cnt].to=y;
e[cnt].next=p[x];
p[x]=cnt;
return ;
} struct Trie
{
private:
int c[][];
int d[];
int cnt,root; public:
void insert(const int val,const int flag)
{
int pos=root,temp;
for(int i=;i>=;--i)
{
temp=!!(val&(<<i));
if(!c[pos][temp])
{
c[pos][temp]=++cnt;
c[cnt][]=c[cnt][]=;
d[cnt]=;
}
d[pos]=max(d[pos],flag);
pos=c[pos][temp];
}
d[pos]=max(d[pos],flag);
return ;
} void query(const int val,const int flag)
{
int temp,num=,pos=root;
for(int i=;i>=;--i)
{
temp=!(val&(<<i));
if(c[pos][temp] && d[c[pos][temp]]+flag>=k)
{
pos=c[pos][temp];
num|=(<<i);
}
else
{
if(!c[pos][temp^] || d[c[pos][temp^]]+flag<k)
{
num=-;
break;
}
else pos=c[pos][temp^];
}
}
if(k<=flag)Ans=max(Ans,val);
Ans=max(Ans,num);
} void clear()
{
root=;
cnt=;
c[root][]=c[root][]=;
d[root]=,d[]=;
return ;
}
}T; int Dfs(const int S,const int fa)
{
Size[S]=;
for(int i=p[S];i;i=e[i].next)
{
if(e[i].to!=fa && !visited[e[i].to])
Size[S]+=Dfs(e[i].to,S);
}
return Size[S];
} void Get(const int S,const int fa,int & Centre,int & tot,const int nn)
{
int Max=,i; for(i=p[S];i;i=e[i].next)
{
if(e[i].to!=fa && !visited[e[i].to])
{
Get(e[i].to,S,Centre,tot,nn);
Max=max(Max,Size[e[i].to]);
}
}
Max=max(Max,nn-Size[S]);
if(tot>Max)tot=Max,Centre=S;
return ;
} void Query(const int S,const int fa,int A,int F)
{
A^=a[S];F+=f[S];
T.query(A,F);
for(int i=p[S];i;i=e[i].next)
{
if(e[i].to!=fa && !visited[e[i].to])
Query(e[i].to,S,A,F);
}
return ;
} void Insert(const int S,const int fa,int A,int F)
{
A^=a[S];F+=f[S];
T.insert(A,F);
for(int i=p[S];i;i=e[i].next)
{
if(e[i].to!=fa && !visited[e[i].to])
Insert(e[i].to,S,A,F);
}
return ;
} void TDC(const int S)
{
int i,Centre; visited[S]=true;
for(i=p[S];i;i=e[i].next)
{
if(!visited[e[i].to])
{
int tot=n+;
Dfs(e[i].to,);
Get(e[i].to,,Centre,tot,Size[e[i].to]);
TDC(Centre);
}
}
T.clear();
for(i=p[S];i;i=e[i].next)
{
if(!visited[e[i].to])
{
Query(e[i].to,,a[S],f[S]);
Insert(e[i].to,,,);
}
}
T.query(a[S],f[S]);
visited[S]=false;
return ;
} int main()
{
int i,x,y; scanf("%d%d",&n,&k);
for(i=;i<=n;++i)scanf("%d",&f[i]);
for(i=;i<=n;++i)scanf("%d",&a[i]); for(i=;i<n;++i)
{
scanf("%d%d",&x,&y);
Add_edge(x,y);
Add_edge(y,x);
} TDC(); printf("%d\n",Ans); return ;
}
[TS-A1486][2013中国国家集训队第二次作业]树[树的重心,点分治]的更多相关文章
- [tsA1491][2013中国国家集训队第二次作业]家族[并查集]
m方枚举,并查集O(1)维护,傻逼题,,被自己吓死搞成神题了... #include <bits/stdc++.h> using namespace std; struct tri { i ...
- [tsA1490][2013中国国家集训队第二次作业]osu![概率dp+线段树+矩阵乘法]
这样的题解只能舔题解了,,,qaq 清橙资料里有.. #include <iostream> #include <cstdio> #include <cstdlib> ...
- [TS-A1489][2013中国国家集训队第二次作业]抽奖[概率dp]
概率dp第一题,开始根本没搞懂,后来看了09年汤可因论文才基本搞懂,关键就是递推的时候做差比较一下,考虑新加入的情况对期望值的贡献,然后推推公式(好像还是不太会推qaq...) #include &l ...
- [TS-A1488][2013中国国家集训队第二次作业]魔法波[高斯消元]
暴力直接解异或方程组,O(n^6)无法接受,那么我们考虑把格子分块,横着和竖着分别分为互不影响的块,这样因为障碍物最多不超过200个,那么块的个数最多为2*(800+200)=2000个,最后用bit ...
- [TS-A1487][2013中国国家集训队第二次作业]分配游戏[二分]
根据题意,设$3n$次比较中胜了$w$次,负了$l$次,平了$d$次,所有场次中胜了$W$次,负了$L$次,平了$D$次.如果一场赢了,那么$w-l$就会$+1$,相同地,$W-L$也会$+1$:如果 ...
- [TS-A1505] [清橙2013中国国家集训队第二次作业] 树 [可持久化线段树,求树上路径第k大]
按Dfs序逐个插入点,建立可持久化线段树,每次查询即可,具体详见代码. 不知道为什么,代码慢的要死,, #include <iostream> #include <algorithm ...
- < < < 2013年国家集训队作业 > > >
完成题数/总题数: 道/37道 1. A1504. Book(王迪): 数论+贪心 ★★☆ 2013中国国家集训队第二次作业 2. A1505. 树(张闻涛): 倍增LCA+可 ...
- [转] ACM中国国家集训队论文集目录(1999-2009)
国家集训队1999论文集 陈宏:<数据结构的选择与算法效率——从IOI98试题PICTURE谈起>来煜坤:<把握本质,灵活运用——动态规划的深入探讨>齐鑫:<搜索方法中的 ...
- BZOJ4317Atm的树&BZOJ2051A Problem For Fun&BZOJ2117[2010国家集训队]Crash的旅游计划——二分答案+动态点分治(点分树套线段树/点分树+vector)
题目描述 Atm有一段时间在虐qtree的题目,于是,他满脑子都是tree,tree,tree…… 于是,一天晚上他梦到自己被关在了一个有根树中,每条路径都有边权,一个神秘的声音告诉他,每个点到其他的 ...
随机推荐
- IDEA Spark程序报错处理
错误一: // :: ERROR Executor: Exception ) java.lang.NoSuchMethodError: scala.Product.$init$(Lscala/Prod ...
- 【转载】Java中Comparable和Comparator比较
[本文转自]http://www.cnblogs.com/skywang12345/p/3324788.html Comparable 简介 Comparable 是排序接口. 若一个类实现了Comp ...
- blockhouses
题意 : 给你一张图上面" X " 代表墙 , " . " 代表空地 , 让你在空地上放置炮台 , 条件是 不能 让彼此的炮台 可以互相看见 ( 隔着墙就看不见 ...
- Android 关于android.os.Build介绍
关于Build类的介绍 这个类为一个获取设备一些初始化信息的类,该类的主要信息都是通过一些static的字段获得: public static final String BOARD The name ...
- POJ 1584 计算几何
思路: 求一遍凸包 用三角形面积(叉积求一下)/边长 求出来高,跟半径比一比 坑点:凸包上三点共线 //By SiriusRen #include <cmath> #include < ...
- Python安装distribute包
从官网https://pypi.python.org/pypi/distribute/0.6.49#downloads上下载distribute包,解压后进入解压文件的目录下,使用 python se ...
- InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析
InnoDB锁机制之Gap Lock.Next-Key Lock.Record Lock解析 有意思,解释的很好
- 字符串String的理解
1.String是一个final的类型 即不可被继承修改,一经生成不可改变.所以在代码中使用String s = s1 + s2;的时候,执行完之后s所指向的是一个新生成的对象,这里有个地方值得注意 ...
- iOS keychain入门
学了很久的iOS,一直都是明文保存用户名和密码在本地,手机一般都是自己用的,而且非越狱手机东西也不怎么能拿到数据,所以也就没在乎那么多,当然,这是不科学的.悄悄的说,这块一直不是我写的~~~ 用户隐私 ...
- CSS——◇demo
核心思想:嵌套盒子中的◇超过父盒子的部分隐藏. 第一种写法: <!DOCTYPE html> <html> <head> <meta charset=&quo ...