luoguP3292 [SCOI2016]幸运数字(点分治做法)
题意
考虑点分治,每次处理过重心的询问(即两点在重心的不同子树中)。
求出每个点到重心的线性基,之后对过重心的询问合并两点线性基求解。
code:
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define mkp make_pair
#define fir first
#define sec second
typedef long long ll;
const int maxn=20010;
const int maxm=200010;
const int inf=1e9;
int n,m,cnt,root,maxsize=inf,trsize;
int head[maxn],size[maxn],check[maxn];
ll a[maxn],ans[maxm];
bool vis[maxn];
vector<pii>ve[maxn];
struct edge{int to,nxt;}e[maxn<<1];
struct Xord
{
ll d[65];
Xord(){memset(d,0,sizeof(d));}
inline void clear(){memset(d,0,sizeof(d));}
inline void insert(ll x)
{
for(int i=61;~i;i--)
{
if(!(x&(1ll<<i)))continue;
if(!d[i]){d[i]=x;return;}
else x^=d[i];
}
}
inline ll query()
{
ll res=0;
for(int i=61;~i;i--)res=max(res,res^d[i]);
return res;
}
}xord[maxn];
inline void add(int u,int v)
{
e[++cnt].nxt=head[u];
head[u]=cnt;
e[cnt].to=v;
}
void getroot(int x,int fa)
{
size[x]=1;
int maxx=0;
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(y==fa||vis[y])continue;
getroot(y,x);size[x]+=size[y];
maxx=max(maxx,size[y]);
}
maxx=max(maxx,trsize-size[x]);
if(maxx<maxsize)maxsize=maxx,root=x;
}
void getxor(int x,int fa)
{
xord[x]=xord[fa];xord[x].insert(a[x]);
for(unsigned int i=0;i<ve[x].size();i++)
{
int y=ve[x][i].fir;
if(check[y]!=root)continue;
Xord tmp=xord[x];
for(int j=0;j<=60;j++)if(xord[y].d[j])tmp.insert(xord[y].d[j]);
ans[ve[x][i].sec]=max(ans[ve[x][i].sec],tmp.query());
}
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(y==fa||vis[y])continue;
getxor(y,x);
}
}
void mark(int x,int fa,int k)
{
check[x]=k;
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(y==fa||vis[y])continue;
mark(y,x,k);
}
}
void solve(int x)
{
//cerr<<x<<endl;
vis[x]=1;check[x]=x;
xord[x].clear();xord[x].insert(a[x]);
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(vis[y])continue;
getxor(y,x);mark(y,x,x);
}
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(vis[y])continue;
maxsize=inf;trsize=size[y];getroot(y,0);
solve(root);
}
}
int main()
{
//freopen("test.in","r",stdin);
//freopen("test.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
for(int i=1;i<n;i++)
{
int u,v;scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
for(int i=1;i<=m;i++)
{
int x,y;scanf("%d%d",&x,&y);
if(x==y)ans[i]=a[x];
else ve[x].push_back(mkp(y,i)),ve[y].push_back(mkp(x,i));
}
trsize=n;maxsize=inf;getroot(1,0);
solve(root);
for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
return 0;
}
luoguP3292 [SCOI2016]幸运数字(点分治做法)的更多相关文章
- luoguP3292 [SCOI2016]幸运数字(倍增做法)
题意 线性基套上树上倍增即可,注意边界. code: #include<bits/stdc++.h> using namespace std; typedef long long ll; ...
- [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2131 Solved: 865[Submit][Statu ...
- BZOJ 4568: [Scoi2016]幸运数字 [线性基 倍增]
4568: [Scoi2016]幸运数字 题意:一颗带点权的树,求树上两点间异或值最大子集的异或值 显然要用线性基 可以用倍增的思想,维护每个点向上\(2^j\)个祖先这些点的线性基,求lca的时候合 ...
- [SCOI2016]幸运数字 树链剖分,线性基
[SCOI2016]幸运数字 LG传送门 为了快乐,我们用树剖写这题. 强行树剖,线段树上每个结点维护一个线性基,每次查询暴力合并. 瞎分析一波复杂度:树剖两点之间\(\log n\)条重链,每条重链 ...
- bzoj 4568: [Scoi2016]幸运数字
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 848 Solved: 336[Submit][Status ...
- [洛谷P3292] [SCOI2016]幸运数字
洛谷题目链接:[SCOI2016]幸运数字 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城 ...
- 【BZOJ 4568】 4568: [Scoi2016]幸运数字 (线性基+树链剖分+线段树)
4568: [Scoi2016]幸运数字 Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个 幸运数字,以纪念碑的形 ...
- [BZOJ4568][Scoi2016]幸运数字 倍增+线性基
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1791 Solved: 685[Submit][Statu ...
- 【BZOJ4568】[Scoi2016]幸运数字 倍增+线性基
[BZOJ4568][Scoi2016]幸运数字 Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念 ...
随机推荐
- 数组中的第K个最大元素
在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2输出: 5示 ...
- [BZOJ1042]AOI2008]硬币购物
题目描述 Description 硬币购物一共有4种硬币.面值分别为\(c_1\) ,\(c_2\) ,\(c_3\) ,\(c_4\) .某人去商店买东西,去了\(tot\) 次.每次带\(d_i\ ...
- springboot实践1
环境安装 安装jdk 推荐安装jkd1.8+,我使用的是mac,假设已经安装好homebrew,则jdk的安装指令是: brew install java 在 ~/zshrc ,添加两行 export ...
- Python - ^在正则表达式中的作用
^在正则表达式中有两个作用,一是表达以什么开头,二是表达对什么取反.有时候经常傻傻的分不清楚,接下来给大家详细介绍该怎么用这个^准备一个python文件test.py,借用re.search函数举例说 ...
- make 命令与 Makefile
make 是一个工具程序,通过读取 Makefile 文件,实现自动化软件构建.虽然现代软件开发中,集成开发环境已经取代了 make,但在 Unix 环境中,make 仍然被广泛用来协助软件开发.ma ...
- 刷抖音太累,教你用Python把高颜值的小姐姐都爬下来慢慢看
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 星安果.AirPython 目 标 场 景 相信大家平时刷抖音短视频 ...
- 用 Python 自动监测 GitHub 项目更新
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: GitPython PS:如有需要Python学习资料的小伙伴可以加 ...
- json字符串转为php数组,使用随机字符串生成订单号(学生笔记)
//提交订单 function add_order(){ session_start(); // var_dump($_SESSION); // die(); // session_destroy() ...
- 易优CMS:type的基础用法
[基础用法] 名称:type 功能:获取指定栏目信息 语法: {eyou:type typeid='栏目ID' empty='暂时没有数据'} <a href="{$field.typ ...
- layui 集成第三方和自定义组件到模块规范
1.新建一个layui.extend.js文件,页面调用时这个文件放到layui.js后面. 2.基础的配置卸载config中,扩展的组件写入extend,组件的路径是相对于config下base的路 ...