推荐模板题
线性基模板
这题的题解写的挺好的大家可以康康
线性基呢
就是从几个数里
选出任意个数
使得它们异或起来得到的数最大
反正那个题解写的真挺好。。
我就不多讲具体原理
这题讲的是一个在线的修改求线性基
里面还要decode一下。。。
那我们就用动态规划的思想
二维dp
线性基尽量取右边的数
然后运用pos数组检查是否在l到r之间
二维dp维护线性基
很巧妙
题解叫这个是上三角形态/线性基前缀和
#include<bits/stdc++.h>
using namespace std;
const int MAXN=500000+10;
int T,n,m,op,l,r,tmp,ans,a[MAXN],f[MAXN][32],pos[MAXN][32];
inline int Read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-f; ch=getchar();}
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
char s[30];
inline void writeln(int x)
{
if (x<0) putchar('-'),x=-x;
if (!x) putchar('0'); else
{
int len=0;
while (x) s[++len]=x%10+'0',x/=10;
while (len) putchar(s[len--]);
}
putchar('\n');
}
inline void Add(int i,int x)
{
int k=i;
for (int j=30;j>=0;--j) f[i][j]=f[i-1][j],pos[i][j]=pos[i-1][j];
for (int j=30;j>=0;--j) if (x>>j)
{
if (!f[i][j])
{
f[i][j]=x;
pos[i][j]=k;
break;
}
else
{
if (k>pos[i][j])
{
tmp=k,k=pos[i][j],pos[i][j]=tmp;
tmp=x,x=f[i][j],f[i][j]=tmp;
}
x^=f[i][j];
}
}
}
int main()
{
//freopen("test.in","r",stdin);
//freopen("test.out","w",stdout);
T=Read();
while (T--)
{
n=Read(),m=Read();
for (int i=1;i<=n;++i) a[i]=Read(),Add(i,a[i]);
ans=0;
while (m--)
{
op=Read();
if (op) a[++n]=Read()^ans,Add(n,a[n]);
else
{
l=Read(),r=Read();
l=(l^ans)%n+1,r=(r^ans)%n+1;
if (l>r) swap(l,r);
ans=0;
for (int j=30;j>=0;--j) if((ans^f[r][j])>ans&&pos[r][j]>=l) ans^=f[r][j];
writeln(ans);
}
}
for (int i=1;i<=n;++i)
for (int j=30;j>=0;--j) f[i][j]=pos[i][j]=0;
}
return 0;
}
拓展练习
洛谷p4570
里面的题解里的线性基博客写的挺好的
线性基的性质概括了一下
这一题使用的线性基和本题类似
更简单一些
建议自己背一下写一下
注意long long位次最高到62
到63会很有意思
大家可以试试
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll ji[100];
int m[1005],pos[1005];
void add(int p,ll t){
int k=p;
for(int i=63;i>=0;i--){
if(t>>(ll)i){
if(!ji[i]){
ji[i]=t;
pos[i]=k;
break;
}else {
if(m[k]>m[pos[i]]){
swap(ji[i],t);
swap(k,pos[i]);
}
t^=ji[i];
}
}
}
}
int main(){
int n,ans=0;
ll t;
scanf("%d",&n);
memset(pos,-1,sizeof(pos));
for(int i=0;i<n;i++){
scanf("%lld%d",&t,&m[i]);
add(i,t);
}
for(int i=0;i<=63;i++){
if(pos[i]!=-1){
ans+=m[pos[i]];
}
}
printf("%d",ans);
return 0;
}