BZOJ4568 [Scoi2016]幸运数字


题目描述

传送门

题目分析

这个题,求树上链的\(XOR\)最大值,可以不选某些点。

考虑到线性基可以用很快的速度求出\(XOR\)的最大值,我们首先可以确定使用线性基来搞定这个题的询问。

然后可以考虑用树剖解决,发现一个问题,使用树剖时,由于一边跳一遍计算线性基,还要合并,复杂度比较高,虽然的确可以通过本题,但是明显可以通过随便增大数据就卡死了。倍增貌似拥有更好的常数,但是,空间利用太低,容易\(MLE\)。

发现每次询问只询问链,那么我们可以使用LCT点分治来解决这个题。

具体方法就是,我们点分治计算每个子树的时候,把询问中lca是这个子树的根的直接求出来然后合并,不是的就把询问传下去,这样复杂度就是\(O(Nlog^2N)\)的,非常优秀可以通过。

是代码呢

#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+7;
#define ll long long
const ll inf=1ll<<61;
ll n,m,a[MAXN],p[MAXN],ans[MAXN],size[MAXN],wson[MAXN],vis[MAXN],U[MAXN],V[MAXN],bel[MAXN],tq[MAXN],sum,root;
bool use[MAXN];
inline ll read()
{ll x=0,c=1;char ch=' ';while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();while(ch=='-')c*=-1,ch=getchar();while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x*c;
}
vector<int> edge[MAXN],q[MAXN];
struct T{ll b[65];inline void clear() {memset(b,0,sizeof(b));}inline void insert(ll x){for(int i=60;~i;i--)if(x>>i&1){if(b[i]) x^=b[i];else {b[i]=x;break;}}}inline void merge(const T &x){for(int i=60;~i;i--){if(x.b[i]) insert(x.b[i]);}}inline ll query(){ll ans=0;for(int i=60;~i;i--){if((ans^b[i])>ans) ans^=b[i];}return ans;}
}base[MAXN];
inline void get_root(int u,int fa)
{size[u]=1;wson[u]=0;for(int i=0;i<edge[u].size();i++){int v=edge[u][i];if(v==fa||vis[v]) continue;get_root(v,u);size[u]+=size[v];if(wson[u]<size[v]) wson[u]=size[v];}if(sum-size[u]>wson[u]) wson[u]=sum-size[u];if(wson[u]<wson[root]) root=u;
}inline void dfs(int u,int fa,int tt){base[u]=base[fa]; bel[u]=tt;base[u].insert(a[u]);for(int i=0;i<edge[u].size();i++){int v=edge[u][i];if(v!=fa&&!vis[v]) dfs(v,u,tt);}
}inline void solve(int x){if(!q[x].size()) return;wson[0]=inf;sum=size[x];root=0;get_root(x,0);int u=root;vis[root]=1;bel[root]=root;base[root].clear();base[root].insert(a[root]);for(int i=0;i<edge[root].size();i++){int v=edge[root][i];if(!vis[v]) dfs(v,root,v);}int tot=q[x].size();for(int i=0;i<tot;i++) tq[i]=q[x][i];q[x].clear();T tmp;ll id;for(int i=0;i<tot;i++){id=tq[i];if(bel[U[id]]==bel[V[id]])q[bel[U[id]]].push_back(id);else tmp=base[U[id]],tmp.merge(base[V[id]]),ans[id]=tmp.query(),use[id]=1;}for(int i=0;i<edge[u].size();i++){int v=edge[u][i];if(vis[v]) continue;solve(v);}
}
int main()
{n=read();m=read();for(int i=1;i<=n;i++) a[i]=read();for(int i=1;i<n;i++){int u=read(),v=read();edge[u].push_back(v);edge[v].push_back(u);}for(int i=1;i<=m;i++){U[i]=read();V[i]=read();if(U[i]==V[i]) ans[i]=a[U[i]];else q[1].push_back(i);}size[1]=n;solve(1);for(int i=1;i<=m;i++) printf("%lld\n", ans[i]);
}

转载于:https://www.cnblogs.com/victorique/p/10277988.html

BZOJ4568 [Scoi2016]幸运数字相关推荐

  1. Bzoj4568: [Scoi2016]幸运数字

    Bzoj4568: [Scoi2016]幸运数字 线性基+倍增+LCA 原来线性基还能这么考--一开始看到这个题以为是树上差分线性基,然而线性基不支持删除,所以就挂了. 后来想到倍增线性基,其实到这里 ...

  2. [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)

    4568: [Scoi2016]幸运数字 Time Limit: 60 Sec  Memory Limit: 256 MB Submit: 2131  Solved: 865 [Submit][Sta ...

  3. [bzoj4568][Scoi2016]幸运数字

    来自FallDream的博客,未经允许,请勿转载,谢谢. A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这 ...

  4. BZOJ4568: [Scoi2016]幸运数字(线性基 倍增)

    题意 题目链接 Sol 线性基是可以合并的 倍增维护一下 然后就做完了?? 喵喵喵? // luogu-judger-enable-o2 #include<bits/stdc++.h> # ...

  5. BZOJ4568 : [Scoi2016]幸运数字

    树的点分治,每次求出重心后,求出重心到每个点路径上的数的线性基. 对于每个询问,只需要暴力合并两个线性基即可. 时间复杂度$O(60n\log n+60^2q)$. #include<cstdi ...

  6. P3292 [SCOI2016]幸运数字(树剖 + 线段树维护线性基)

    P3292 [SCOI2016]幸运数字 思路 如果这题是求x,yx, yx,y之间的距离显然我们可以通过树剖加线段树来写, 但是这里变成了求任意个数的异或最大值.如果给定区间我们显然可以通过线性基来 ...

  7. [洛谷P3292] [SCOI2016]幸运数字

    洛谷题目链接:[SCOI2016]幸运数字 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城 ...

  8. bzoj 4568: [Scoi2016]幸运数字(树上倍增+线性基)

    4568: [Scoi2016]幸运数字 Time Limit: 60 Sec  Memory Limit: 256 MB Submit: 1692  Solved: 643 [Submit][Sta ...

  9. BZOJ4568:[SCOI2016]幸运数字——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4568 https://www.luogu.org/problemnew/show/P3292 A ...

最新文章

  1. linux删除指定创建时间文件(文件夹)脚本
  2. linux 终端 渐变色,iOS开发——UI篇文字渐变效果:图层中的mask属性
  3. Scrapy框架----- Spiders
  4. ROBOMASTER 2018机甲大师赛 南部赛区三等奖!
  5. [迷宫中的算法实践]迷宫生成算法——Prim算法
  6. PL/SQL Developer连接Oracle 11g在Win8 64位系统下乱码
  7. ubuntu下使用vi退出终端出现乱码的解决方案
  8. 001 基本的环境的安装
  9. 【沫沫金】安卓手机版 - 日期控件
  10. Oracle数据库基础知识(一)
  11. 利用Python将excel或csv文件导入到mysql数据库中
  12. 小米笔记本适合计算机专业吗,真Pro还是假专业?细说小米新笔记本电脑五宗罪...
  13. 详解两个栈实现一个队列(python实现——经典面试题)
  14. [转]ASP.NET 安全认证(三): 用Form 表单认证实现单点登录
  15. 【学习资源】光学、物理类、电子学实验合集
  16. MySQL数据查询之多表查询
  17. 禁用vmware虚拟机自动挂起功能
  18. 达人评测 i5 12500h和锐龙r5 5600h选哪个好
  19. flutter 登录和退出登录_Flutter从入门到奔溃(一):撸一个登录界面
  20. 伦敦8分钟,英国人在BBC上的留言,

热门文章

  1. c语言 搜索彩票期数,根据福利彩票的规则用c++编写一个买彩票开奖的程序,求程序代码,谢谢...
  2. java去哪导包_在Java语言中,哪一个包中的类是自动导入的?( )java.applet
  3. AcWing 874. 筛法求欧拉函数(欧拉函数)
  4. AcWing 240. 食物链
  5. 第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛题解
  6. 洛谷【数据结构1-1】线性表
  7. python gui下载进度条_对python GUI实现完美进度条的示例详解
  8. python︱apple开源机器学习框架turicreate中的SFrame——新形态pd.DataFrame
  9. docker︱在nvidia-docker中使用tensorflow-gpu/jupyter
  10. caffe︱cifar-10数据集quick模型的官方案例