bzoj 4568: [Scoi2016]幸运数字
4568: [Scoi2016]幸运数字
Time Limit: 60 Sec Memory Limit: 256 MB
Submit: 848 Solved: 336
[Submit][Status][Discuss]
Description

然后发现果然合并有更NB的方法。
不是高斯消元(原谅我zz),而是应该一个一个插。
终于19sA掉了。
52s
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define N 20005
using namespace std;
int read()
{
int p=;char c=getchar();
while(c<''||c>'')c=getchar();
while(c>=''&&c<='')p=p*+c-'',c=getchar();
return p;
}
int n,m;
int head[N],ver[N*],nxt[N*],tot;
ll mi[N];
void add(int a,int b)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;return ;
}
ll ji[N][][];
int fa[N][],dep[N];
ll a[N];
void dfs(int x,int f)
{
for(int i=head[x];i;i=nxt[i])
{
if(ver[i]==f)continue;
fa[ver[i]][]=x;
dep[ver[i]]=dep[x]+;
ji[ver[i]][][]=;
ji[ver[i]][][]=a[ver[i]];
dfs(ver[i],x);
}
return ;
}
ll tmp[];
void guess()
{
int k=;int now=tmp[];
for(int i=;i>=;i--)
{
int p=;ll o=mi[i];
for(int j=k;j<=now;j++)
{
if((tmp[j]&o))
{
p=j;break;
}
}
if(p)
{
swap(tmp[p],tmp[k]);
for(int j=;j<=now;j++)
{
if(j!=k&&(tmp[j]&o))
{
tmp[j]^=tmp[k];
}
}k++;
}
}
tmp[]=k-;
}
void yu()
{
for(int i=;i<=;i++)
{
for(int j=;j<=n;j++)
{
tmp[]=ji[j][i-][]+ji[fa[j][i-]][i-][];
for(int k=;k<=ji[j][i-][];k++)tmp[k]=ji[j][i-][k];
for(int k=;k<=ji[fa[j][i-]][i-][];k++)tmp[k+ji[j][i-][]]=ji[fa[j][i-]][i-][k];
guess();
for(int k=;k<=tmp[];k++)ji[j][i][k]=tmp[k];
fa[j][i]=fa[fa[j][i-]][i-];
}
}return ;
}
void solve(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;i--)
{
if(dep[fa[x][i]]>=dep[y])
{
for(int j=;j<=ji[x][i][];j++)tmp[]++,tmp[tmp[]]=ji[x][i][j];
guess();
x=fa[x][i];
}
}
if(x!=y)
{
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i])
{
for(int k=;k<=ji[x][i][];k++)tmp[]++,tmp[tmp[]]=ji[x][i][k];
guess();
for(int k=;k<=ji[y][i][];k++)tmp[]++,tmp[tmp[]]=ji[y][i][k];
guess();
x=fa[x][i];y=fa[y][i];
}
}
tmp[]++;tmp[tmp[]]=a[fa[x][]];
tmp[]++;tmp[tmp[]]=a[x];
tmp[]++;tmp[tmp[]]=a[y];
}
else
{
tmp[]++,tmp[tmp[]]=a[x];
}
guess();
ll now=;
for(int i=tmp[];i>=;i--)
{
now^=tmp[i];
}
printf("%lld\n",now);
return ;
}
int main()
{
int q;
mi[]=;
for(int i=;i<=;i++)mi[i]=mi[i-]*;
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
scanf("%lld",&a[i]);
}
int t1,t2,t3;
for(int i=;i<n;i++)
{
t1=read();t2=read();
add(t1,t2);add(t2,t1);
}
dep[]=;
ji[][][]=;ji[][][]=a[];
dfs(,-);
yu();
for(int i=;i<=q;i++)
{
t1=read();t2=read();
memset(tmp,,sizeof(tmp));
solve(t1,t2);
}
return ;
}
19s
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define N 20005
using namespace std;
int read()
{
int p=;char c=getchar();
while(c<''||c>'')c=getchar();
while(c>=''&&c<='')p=p*+c-'',c=getchar();
return p;
}
int n,m;
int head[N],ver[N*],nxt[N*],tot;
ll mi[N];
void add(int a,int b)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;return ;
}
ll ji[N][][];
int fa[N][],dep[N];
ll a[N];
void dfs(int x,int f)
{
for(int i=head[x];i;i=nxt[i])
{
if(ver[i]==f)continue;
fa[ver[i]][]=x;
dep[ver[i]]=dep[x]+;
for(int j=;j>=;j--)
{
if(a[ver[i]]&mi[j])
{
ji[ver[i]][][j]=a[ver[i]];
break;
}
}
dfs(ver[i],x);
}
return ;
}
ll tmp[];
void insert(ll x)
{
for(int i=;i>=;i--)
{
if(x&mi[i])
{
if(!tmp[i])
{
tmp[i]=x;
break;
}
else x^=tmp[i];
}
}return ;
}
void yu()
{
for(int i=;i<=;i++)
{
for(int j=;j<=n;j++)
{
for(int k=;k<=;k++)tmp[k]=ji[j][i-][k];
for(int k=;k<=;k++)
{
if(ji[fa[j][i-]][i-][k])insert(ji[fa[j][i-]][i-][k]);
}
for(int k=;k<=;k++)ji[j][i][k]=tmp[k];
fa[j][i]=fa[fa[j][i-]][i-];
}
}return ;
}
void solve(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;i--)
{
if(dep[fa[x][i]]>=dep[y])
{
for(int j=;j<=;j++)if(ji[x][i][j])insert(ji[x][i][j]);
x=fa[x][i];
}
}
if(x!=y)
{
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i])
{
for(int k=;k<=;k++)if(ji[x][i][k])insert(ji[x][i][k]);
for(int k=;k<=;k++)if(ji[y][i][k])insert(ji[y][i][k]);
x=fa[x][i];y=fa[y][i];
}
}
insert(a[fa[x][]]);insert(a[x]);insert(a[y]);
}
else
{
insert(a[x]);
}
ll now=;
for(int i=;i>=;i--)
{
now=max(now,now^(tmp[i]));
}
printf("%lld\n",now);
return ;
}
int main()
{
int q;
mi[]=;
for(int i=;i<=;i++)mi[i]=mi[i-]*;
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
scanf("%lld",&a[i]);
}
int t1,t2,t3;
for(int i=;i<n;i++)
{
t1=read();t2=read();
add(t1,t2);add(t2,t1);
}
dep[]=;
for(int i=;i>=;i--)
{
if(a[]&mi[i])
{
ji[][][i]=a[];
break;
}
}
dfs(,-);
yu();
for(int i=;i<=q;i++)
{
t1=read();t2=read();
memset(tmp,,sizeof(tmp));
solve(t1,t2);
}
return ;
}
bzoj 4568: [Scoi2016]幸运数字的更多相关文章
- BZOJ 4568: [Scoi2016]幸运数字 [线性基 倍增]
4568: [Scoi2016]幸运数字 题意:一颗带点权的树,求树上两点间异或值最大子集的异或值 显然要用线性基 可以用倍增的思想,维护每个点向上\(2^j\)个祖先这些点的线性基,求lca的时候合 ...
- BZOJ 4568 [Scoi2016]幸运数字(树链剖分 + 异或线性基)
题目链接 BZOJ 4568 考虑树链剖分+线段树维护每一段区域的异或线性基 对于每个询问,求出该点集的异或线性基.然后求一下这个线性基里面能异或出的最大值即可. #include <bits ...
- bzoj 4568: [Scoi2016]幸运数字【树链剖分+线段树+线性基】
一眼做法,好处是好想好写坏处是常数大,容易被卡(bzoj loj 洛谷开O2 能AC,不开有90分-- 大概就是树剖之后维护线段树,在线段树的每个节点上上维护一个线性基,暴力\( 60^2 \)的合并 ...
- BZOJ 4568 [Scoi2016]幸运数字 ——线性基 倍增
[题目分析] 考虑异或的最大值,维护线性基就可以了. 但是有多次的询问,树剖或者倍增都可以. 想了想树剖动辄数百行的代码. 算了,我还是写倍增吧. 注:被位运算和大于号的优先级坑了一次,QaQ [代码 ...
- BZOJ 4568: [Scoi2016]幸运数字(倍增+线性基)
传送门 解题思路 异或最大值肯定线性基了,树上两点那么就倍增搞一搞,就维护每个点到各级祖先的线性基,时间复杂度\(O(nlog^3n)\),并不知道咋过去的. 代码 #include<iostr ...
- 【BZOJ 4568】 4568: [Scoi2016]幸运数字 (线性基+树链剖分+线段树)
4568: [Scoi2016]幸运数字 Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个 幸运数字,以纪念碑的形 ...
- BZOJ.4516.[SCOI2016]幸运数字(线性基 点分治)
题目链接 线性基可以\(O(log^2)\)暴力合并.又是树上路径问题,考虑点分治. 对于每个点i求解 LCA(u,v)==i 时的询问(u,v),只需求出这个点到其它点的线性基后,暴力合并. LCA ...
- [BZOJ4568][Scoi2016]幸运数字 倍增+线性基
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1791 Solved: 685[Submit][Statu ...
- [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2131 Solved: 865[Submit][Statu ...
随机推荐
- Hyperledger Fabric 1.0.1至Hyperledger Fabric 1.0.5所升级的内容及修复的问题
基础更新 各版本每次迭代都会有一些基础更新内容,如文档修改覆盖.测试用例完善.用户体验改进及删除冗余无效代码等… 下面分类介绍的是一些版本迭代的重要更新内容,因个人实操和理解有限,部分更新并未明确,如 ...
- notion笔记
不错的笔记应用, 模式新颖, 正在使用, 如有相同使用者可以入群交流 notion QQ群 725638123
- JS中判断对象是不是数组的方法
JavaScript中检测对象的方法 1.typeof操作符 这种方法对于一些常用的类型来说那算是毫无压力,比如Function.String.Number.Undefined等,但是要是检测Arra ...
- C++ 类的定义与实现
摘自这篇博客https://blog.csdn.net/xulingxin/article/details/81335030 一."类" 的介绍 在C++中, 用 &q ...
- 新手学ajax2
今天主要解决了一个困扰两天的ajax问题,就是关于从服务器获取数据时的同步和异步问题 , xhr.open("GET", url,false): 这里有三个参数“GET”表示获取的 ...
- 作业6 团队项目之需求 (NABCD模型)
N A B C D模型分析 WorkGroup:NewApps 组员:欧其锋(201306114305 http://www.cnblogs.com/ouqifeng/) 吕日荣(20130611 ...
- TCP系列54—拥塞控制—17、AQM及ECN
一.概述 ECN的相关内容是在RFC3168中定义的,这里我简单描述一下RFC3168涉及的主要内容. 1.AQM和RED 目前TCP中多数的拥塞控制算法都是通过缓慢增加拥塞窗口直到检测到丢包来进行慢 ...
- 弹出提示框的方式——java
1.显示一个错误对话框,该对话框显示的 message 为 'alert': JOptionPane.showMessageDialog(null, "alert", " ...
- Beta版本发布140字评论
1.飞天小女警组: 礼物挑选工具:系统界面十分新颖,相比于前阶段,增加了账号登陆的功能,并且还根据不同的价位区间添加了礼物的图片,并根据礼物的受欢迎程度添加了top10的功能,并且增加了关于本网站的问 ...
- sql%bulk_rowcount && sql%rowcount 的使用
说明: %BULK_ROWCOUNT 属性计算FORALL迭代影响行数 在进行SQL数据操作语句时,SQL引擎打开一个隐式游标(命名为SQL),该游标的标量属性(scalar attribute)有 ...