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 ...
随机推荐
- 在IIS中部署Asp.Net网站
在IIS中部署Asp.Net网站 1.添加IIS或者删除IIS,在控制面板=>程序和功能=>打开或关闭功能 启动iis,右键计算机=>管理=>服务和应用程序=>Inter ...
- 【Docker】第一篇 Docker的初始化安装部署
一.Docker基础 Dacker倡导的理念:一个容器一个进程 Docker的版本了解: Docker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE. 社区版是免费提供给个人 ...
- MySQL基础练习(二)
第一个例子我们编写一个 SQL 查询,列出所有超过或等于5名学生的课. 先建表 CREATE TABLE courses( student ) NOT NULL, class ) NOT NULL ) ...
- Xiuno BBS 4.0 修改时间显示
修罗开源轻论坛程序 - Xiuno BBS 4.0Xiuno BBS 4.0 是一款轻论坛产品,前端基于 BootStrap 4.0.JQuery 3,后端基于 PHP/7 MySQL XCache/ ...
- Homebrew -- 安装与使用
使用 React Native,必须安装的依赖有:Node.Watchman 和 React Native 命令行工具以及 Xcode. 推荐使用Homebrew来安装 Node 和 Watchman ...
- asp.net如何隐藏表格(table)的一行
直接用jquery $("#id1").click(function(){ $("#trId").css("display""no ...
- 牛客网国庆集训派对Day4题目 2018年
链接:https://www.nowcoder.com/acm/contest/204/A来源:牛客网 深度学习 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 1048576K,其他 ...
- Alpha版本冲刺(五)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...
- lintcode-513-完美平方
513-完美平方 给一个正整数 n, 找到若干个完全平方数(比如1, 4, 9, ... )使得他们的和等于 n.你需要让平方数的个数最少. 样例 给出 n = 12, 返回 3 因为 12 = 4 ...
- CANopen 基础
1. TPDO和RPDO都是针对从站来说的,协议上没有有讲任何一个关于主站的概念,协议就只是定义从站,没有定义主站任何东西.TPDO:从站->主站RPDO:主站->从站 2. PDO的CO ...