Xor && 线性基练习
#include <cstdio>
#include <cstring>
const int Len=;
const int Maxn=;
int cnt,Ans,b,x,n;
inline int Max(int x,int y) {return x>y?x:y;}
struct Node {int next[];}Tree[Maxn*Len];
void Insert(int x)
{
int Now=; bool k;
for (int i=Len;i>=;i--)
{
k=x&(<<i);
if (Tree[Now].next[k]==-) Tree[Now].next[k]=++cnt;
Now=Tree[Now].next[k];
}
}
int Query(int x)
{
int Now=,v=; bool k;
for (int i=Len;i>=;i--)
{
k=x&(<<i);
if (Tree[Now].next[!k]!=-) k=!k;
v=v|(k<<i);
Now=Tree[Now].next[k];
}
return v;
}
int main()
{
// freopen("c.in","r",stdin);
while (scanf("%d",&n)!=EOF)
{
Ans=cnt=; memset(Tree,-,sizeof(Tree));
for (int i=;i<=n;i++)
{
scanf("%d",&x);
Insert(x);
Ans=Max(Ans,x^Query(x));
}
printf("%d\n",Ans);
}
return ;
}
CSU1216
在n个数取两个Xor最大。用0-1Trie.
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
LL n,Ans,Base[];
struct Node{LL a,b;}A[];
inline bool cmp(Node A,Node B) {return A.b>B.b;} int main()
{
scanf("%lld",&n);
for (LL i=;i<=n;i++) scanf("%lld%lld",&A[i].a,&A[i].b);
sort(A+,A+n+,cmp); Ans=;
for (LL i=;i<=n;i++)
{
for (LL j=;j>=;j--)
if (A[i].a>>j&)
{
if (!Base[j])
{
Base[j]=A[i].a;
break;
}
A[i].a^=Base[j];
}
if (A[i].a) Ans+=A[i].b;
}
printf("%lld\n",Ans);
return ;
}
BZOJ2460
若子集异或为0,则集合一定不为线性基。从大到小排序,贪心即可。
#include <cstdio>
#include <iostream>
using namespace std;
#define LL long long
const LL Maxn=;
LL a[Maxn],Kase,n,Ans,k,q,Bin[];
inline void Swap(LL &x,LL &y) {LL t=x;x=y;y=t;}
inline LL Get(LL Row,LL k)
{
if (Row<n)
{if (k==) return ; else k--;}
if (k>=Bin[Row]) return -;
LL Ret=;
for (int i=;i<=Row;i++)
if (k&Bin[Row-i]) Ret^=a[i];
return Ret;
}
int main()
{
scanf("%I64d",&Kase);
Bin[]=; for (int i=;i<=;i++) Bin[i]=Bin[i-]<<;
for (LL kase=;kase<=Kase;kase++)
{
printf("Case #%I64d:\n",kase);
scanf("%I64d",&n);
for (LL i=;i<=n;i++) scanf("%I64d",&a[i]);
LL Now=;
for (LL i=Bin[];i;i>>=)
{
LL j=Now+;
while (!(i&a[j])&&j<=n) j++;
if (j==n+) continue;
++Now; Swap(a[Now],a[j]);
for (j=;j<=n;j++)
{
if (j==Now) continue;
if (a[j]&i) a[j]=a[j]^a[Now];
}
}
scanf("%I64d",&q);
for (LL i=;i<=q;i++)
{
scanf("%I64d",&k);
printf("%I64d\n",Get(Now,k));
}
}
return ;
}
HDU3949
求第K大的Xor和,求出线性基,把K转为二进制在Xor就可以了
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
const LL Mod=;
const LL Maxn=;
struct Node{LL b[Maxn],c;}a[Maxn];
LL Base[Maxn],cnt,Ans,n,m;
inline LL Pow(LL x,LL y)
{
LL Ret=;
while (true)
{
if (y&) Ret=(Ret*x)%Mod;
x=(x*x)%Mod; y>>=;
if (y==) break;
}
return Ret;
}
inline bool cmp(Node A,Node B) {return A.c<B.c;}
int main()
{
scanf("%lld%lld",&n,&m);
for (LL i=;i<=n;i++)
for (LL j=;j<=m;j++) scanf("%lld",&a[i].b[j]);
for (LL i=;i<=n;i++) scanf("%lld",&a[i].c);
sort(a+,a+n+,cmp);
for (LL i=;i<=n;i++)
{
bool flag=false;
for (LL j=;j<=m;j++)
if (a[i].b[j])
{
if (!Base[j])
{
Base[j]=i; flag=true;
break;
}
LL t=Mod-(a[i].b[j]*Pow(a[Base[j]].b[j],Mod-))%Mod;
for (LL k=j;k<=m;k++)
a[i].b[k]=(a[i].b[k]+(t*a[Base[j]].b[k])%Mod)%Mod;
}
if (flag) Ans+=a[i].c,cnt++;
}
printf("%lld %lld\n",cnt,Ans);
return ;
}
BZOJ4004
即求出线性基,然后贪心取即可。
#include <cstdio>
#include <cstring>
#define LL long long
inline void Get_Int(LL & x)
{
char ch=getchar(); x=;
while (ch<'' || ch>'') ch=getchar();
while (ch>='' && ch<='') {x=x*+ch-'';ch=getchar();}
}
inline void Swap(LL &x,LL &y) {LL t=x;x=y;y=t;}
inline LL Max(LL x,LL y) {return x>y?x:y;}
inline LL Min(LL x,LL y) {return x>y?y:x;}
//==================================================
const LL Maxn=;
LL head[Maxn],father[Maxn][],Dep[Maxn],n,m,Bin[],x,u,v,cnt,Sum;
bool vis[Maxn];
struct Edge{LL to,next;}edge[Maxn<<];
struct Base
{
LL a[];
inline void Clr() {memset(a,,sizeof(a));}
inline void Insert(LL x)
{
for (LL i=;i>=;i--)
if (Bin[i]&x)
{
if (!a[i]) {a[i]=x; return;}
x^=a[i];
}
}
};
Base f[Maxn][],Ans;
inline void Add(LL u,LL v) {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
void Dfs(LL u)
{
vis[u]=true;
for (LL i=head[u];i!=-;i=edge[i].next)
if (!vis[edge[i].to])
{
father[edge[i].to][]=u;
Dep[edge[i].to]=Dep[u]+;
Dfs(edge[i].to);
}
}
inline void Init()
{
for (LL j=;j<=;j++)
for (LL i=;i<=n;i++)
{
father[i][j]=father[father[i][j-]][j-];
for (LL k=;k>=;k--) if (f[i][j-].a[k])f[i][j].Insert(f[i][j-].a[k]);
for (LL k=;k>=;k--) if (f[father[i][j-]][j-].a[k])f[i][j].Insert(f[father[i][j-]][j-].a[k]);
}
}
void Solve(LL u,LL v)
{
if (Dep[u]<Dep[v]) Swap(u,v);
for (LL i=;i>=;i--)
if (Dep[father[u][i]]>=Dep[v])
{
for (LL k=;k>=;k--) if (f[u][i].a[k]) Ans.Insert(f[u][i].a[k]);
u=father[u][i];
}
if (u==v)
{
for (LL k=;k>=;k--) if (f[u][].a[k]) Ans.Insert(f[u][].a[k]);
return;
} for (LL i=;i>=;i--)
if (father[u][i]!=father[v][i])
{
for (LL k=;k>=;k--) if (f[u][i].a[k]) Ans.Insert(f[u][i].a[k]);
for (LL k=;k>=;k--) if (f[v][i].a[k]) Ans.Insert(f[v][i].a[k]);
u=father[u][i],v=father[v][i];
}
for (LL k=;k>=;k--) if (f[u][].a[k])Ans.Insert(f[u][].a[k]);
for (LL k=;k>=;k--) if (f[v][].a[k])Ans.Insert(f[v][].a[k]);
for (LL k=;k>=;k--) if (f[father[u][]][].a[k])Ans.Insert(f[father[u][]][].a[k]);
} int main()
{
Bin[]=; for (LL i=;i<=;i++) Bin[i]=Bin[i-]<<;
Get_Int(n),Get_Int(m);
for (LL i=;i<=n;i++)
{
Get_Int(x);
f[i][].Insert(x);
}
memset(head,-,sizeof(head));
for (LL i=;i<n;i++)
{
Get_Int(u),Get_Int(v);
Add(u,v),Add(v,u);
}
father[][]=; Dep[]=;
memset(vis,false,sizeof(vis)); Dfs();
Init();
for (LL i=;i<=m;i++)
{
Get_Int(u),Get_Int(v);
Ans.Clr();
Solve(u,v); Sum=;
for (LL j=;j>=;j--) Sum=Max(Sum,Sum^Ans.a[j]);
printf("%lld\n",Sum);
}
return ;
}
BZOJ4568
倍增合并线性基,贪心求最大值即可
Xor && 线性基练习的更多相关文章
- 【BZOJ-2115】Xor 线性基 + DFS
2115: [Wc2011] Xor Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2142 Solved: 893[Submit][Status] ...
- BZOJ.2115.[WC2011]Xor(线性基)
题目链接 \(Description\) 给定一张无向带边权图(存在自环和重边).求一条1->n的路径,使得路径经过边的权值的Xor和最大.可重复经过点/边,且边权和计算多次. \(Soluti ...
- BZOJ2115:[WC2011] Xor(线性基)
Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...
- HDU3949 XOR (线性基)
HDU3949 XOR Problem Description XOR is a kind of bit operator, we define that as follow: for two bin ...
- [hdu3949]XOR(线性基求xor第k小)
题目大意:求xor所有值的第k小,线性基模板题. #include<cstdio> #include<cstring> #include<algorithm> #i ...
- HDU3949 XOR(线性基第k小)
Problem Description XOR is a kind of bit operator, we define that as follow: for two binary base num ...
- 2019牛客多校第一场H XOR 线性基模板
H XOR 题意 给出一组数,求所有满足异或和为0的子集的长度和 分析 n为1e5,所以枚举子集肯定是不可行的,这种时候我们通常要转化成求每一个数的贡献,对于一组数异或和为0.我们考虑使用线性基,对这 ...
- BZOJ 2115 [Wc2011] Xor ——线性基
[题目分析] 显然,一个路径走过两边是不需要计算的,所以我么找到一条1-n的路径,然后向该异或值不断异或简单环即可. 但是找出所有简单环是相当复杂的,我们只需要dfs一遍,找出所有的环路即可,因为所有 ...
- BZOJ 2844: albus就是要第一个出场 [高斯消元XOR 线性基]
2844: albus就是要第一个出场 题意:给定一个n个数的集合S和一个数x,求x在S的$2^n$个子集从小到大的异或和序列中最早出现的位置 一开始看错题了...人家要求的是x第一次出现位置不是第x ...
随机推荐
- Android 6编译环境搭建 (Marshmallow)
1.安装 ubuntu 14.03 尽管android推荐 ubuntu 15, 安全起见,还是装LTS的14.04,步骤跳过 2. JDK: Marshmallow 需要 JDK8 ,添个源,顺手配 ...
- 采购信息记录修改[BDC]
*&---------------------------------------------------------------------* *& *&---------- ...
- UISegmentControl
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- 矩阵k次幂 采用三重循环
#include<iostream> using namespace std; int main() { int n,k; ][],b[][],c[][]; while(cin>&g ...
- SQLSERVER2008R2数据库的整体导出及单个表的导出步骤
今天在同事导SQLSERVER数据库中的表的时候遇到一问题,不知道怎么单独的把一个表的建表语句导出来,,迅速百度一下,按照步骤还真导出来了,导出单个表的步骤看下面来啦....: 点中数据库名字---- ...
- PHP实现微信公众平台开发 全套视频资源下载
好久没有在博客园更新东西了,今天给大家分享一份比较不错的视频学习资源吧. 主要是关于PHP实现微信公众平台开发, 不知道大家对于微信平台的开发有多少了解,那么今天就从基础开始吧,资源目录如下(PS ...
- using border-radius to make a worker
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...
- EntityFrame Work:No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlClient'
今天试着学习了Entity Frame Work遇到的问题是 The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlP ...
- [移动端]rem适配
原理:给html根节点设置一个基础font-size值,然后页面的所有元素布局均相对于该font-size值采用rem单位设定.font-size的取值通过js计算. 但字体不用rem单位,原因如下: ...
- UIControl
//当遇到button上添加图片,不显示图片,而显示蓝色,解决方案 //1.button的类型,改成UIButtonTypeCustom //2.button的set使用setBackgroundIm ...