[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…… 于是,一天晚上他梦到自己被关在了一个有根树中,每条路径都有边权,一个神秘的声音告诉他,每个点到其他的 ...
随机推荐
- javaEE框架获取和传参要使用的类和接口
1:spring 2:struts2获取前台数据(action中获取) //4修改用户密码. public String updateUserPassword() throws Exception{ ...
- 洛谷P1387最大正方形(dp,前缀和)
题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m ...
- akka设计模式系列-慎用ask
慎用ask应该是Akka设计的一个准则,很多时候我们应该禁用ask.之所以单独把ask拎出来作为一篇博文,主要是akka的初学者往往对ask的使用比较疑惑. "Using ask will ...
- VUE element-ui下拉列表获取label值
有这样一个场景,当我们往后台数据传的是id时,我们却想在前台获取列表显示的值,这时候可以用下面的方法来获取你想要的label值 let obj = {}; obj = this.arr.find((i ...
- JavaScript判断对象数组中是否存在某个对象【转】
1. 如果要判断数组中是否存在某个元素的话很好判断,直接用数组的indexOf方法就好,存在返回当前索引不存在返回-1 var arr=[1,2,3,4] arr.indexOf(3) arr.ind ...
- Android从Camera中获取图片的两种方法
方法一: 此方法会由Camera直接产生照片回传给应用程序,但是返回的是压缩图片,显示不清晰 ? 1 2 3 4 5 6 try { Intent cameraIntent = new In ...
- Java——Spring配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- asp.net——根据时间,显示内容
题目: 在VS 2010中建立一个网站,命名为Lab5_1,建立时注意项目文件夹的存放位置.根据当前时间,在页面上显示早上好或下午好或晚上好,并显示相应的不同图片. 体验: 一开始看到这个题目的时候, ...
- 探索java世界中的日志奥秘
java日志简单介绍 对于一个应用程序来说日志记录是必不可少的一部分.线上问题追踪,基于日志的业务逻辑统计分析等都离不日志.JAVA领域存在多种日志框架,目前常用的日志 ...
- 回顾Google IO 2016 -Keynote【图解】
Google IO大会倒计时进行中~~ 两名演奏者在使用高空“古筝”. 最后5秒倒计时~~~~全场轰动~ 倒计时结束,IO大会正式开始.屏幕中,一个人把纯白的唱片放入唱片机中. 然后欢快的音乐响起,台 ...