线性代数
P3812 【模板】线性基
模板题
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int D=64;
int n;
ll w[D];
bool insert(ll x){
for(int i=D-1;i>=0;i--){
if((x>>i)&1){
if(w[i]) x^=w[i];
else{
w[i]=x;
return true;
}
}
}
return false;
}
void simp(){
for(int i=D-1;i>=0;i--){
if(w[i]!=0){
for(int j=D-1;j>i;j--){
if((w[j]>>i)&1){
w[j]^=w[i];
}
}
}
}
}
ll maxxxor(){
ll ans=0;
for(int i=D-1;i>=0;i--){
if(w[i]) ans^=w[i];
}
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
ll x;
scanf("%lld",&x);
insert(x);
}
simp();
cout<<maxxxor();
}
P4570 [BJWC2011] 元素
- 题意:
给你
- 思路:
将魔力
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int D=64;
ll w[D];
int n;
struct md{
int b;
ll a;
}z[1004];
bool insert(ll x){
for(int i=D-1;i>=0;i--){
if((x>>i)&1){
if(w[i]) x^=w[i];
else{
w[i]=x;
return true;
}
}
}
return false;
}
void simp(){
for(int i=D-1;i>=0;i--){
if(w[i]!=0){
for(int j=D-1;j>i;j--){
if(w[j]!=0) w[j]^=w[i];
}
}
}
}
bool cmp(md x,md y){
return x.b>y.b;
}
ll ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%lld%d",&z[i].a,&z[i].b);
}
sort(z+1,z+1+n,cmp);
for(int i=1;i<=n;i++){
if(insert(z[i].a)){
ans+=z[i].b;
}
else continue;
}
cout<<ans;
}
P4151 [WC2011] 最大XOR和路径
- 题意:
在一个图中找一条从
- 思路:
可以证明这样的一条路径是由一条链加上一些环构成的,于是
之所以是随便一条链,因为我们发现如果选择链
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
struct node{
int to,nxt;
ll w;
}z[200004];
int cnt,h[500004];
void add(int x,int y,ll w){
z[++cnt].to=y;
z[cnt].nxt=h[x];
z[cnt].w=w;
h[x]=cnt;
}
int vis[500004];
ll dn[500004];
const int D=64;
ll w[D];
void insert(ll x){
for(int i=D-1;i>=0;i--){
if((x>>i)&1){
if(w[i]){
x^=w[i];
}
else{
w[i]=x;
return ;
}
}
}
}
void dfs(int x,ll res){
dn[x]=res,vis[x]=1;
for(int i=h[x];i;i=z[i].nxt){
int y=z[i].to;
if(vis[y]){
insert(res^z[i].w^dn[y]);
}
else{
dfs(y,res^z[i].w);
}
}
}
ll qury(ll x){
ll ans=x;
for(int i=D-1;i>=0;i--){
ans=max(ans,ans^w[i]);
}
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v;
ll w;
scanf("%d%d%lld",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
dfs(1,0);
cout<<qury(dn[n]);
}
P3292 [SCOI2016] 幸运数字
- 题意:
给你一棵树,给定
- 思路:
找到
为了让答案尽可能大,我们要把线性基往深处插入,所以在插入过程中判断下深度即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q;
struct edge{
int to,nxt;
}z[400004];
const int D=64;
struct tree{
int dep,fa,maxxson,son,top;
int pos[D],w[D];
}l[100003];
int h[100003];
int cnt;
void add(int x,int y){
z[++cnt].to=y;
z[cnt].nxt=h[x];
h[x]=cnt;
}
int a[300003];
void dfs(int x,int fa){
l[x].fa=fa;
l[x].dep=l[fa].dep+1;
l[x].son=1;
l[l[x].maxxson].son=-1;
for(int i=D-1;i>=0;i--) l[x].pos[i]=l[fa].pos[i],l[x].w[i]=l[fa].w[i];
int X=a[x],_x=x;
for(int i=D-1;i>=0;i--){
if((X>>i)&1){
if(l[x].w[i]){
if(l[_x].dep>l[l[x].pos[i]].dep) swap(_x,l[x].pos[i]),swap(X,l[x].w[i]);
X^=l[x].w[i];
}
else{
l[x].w[i]=X;
l[x].pos[i]=_x;
break;
}
}
}
for(int i=h[x];i;i=z[i].nxt){
int y=z[i].to;
if(y==l[x].fa) continue;
else{
dfs(y,x);
l[x].son+=l[y].son;
if(l[y].son>l[l[x].maxxson].son){
l[x].maxxson=y;
l[l[x].maxxson].son=l[y].son;
}
}
}
}
void Dfs(int x,int top){
l[x].top=top;
if(!l[x].maxxson) return ;
Dfs(l[x].maxxson,top);
for(int i=h[x];i;i=z[i].nxt){
int y=z[i].to;
if(y==l[x].fa||y==l[x].maxxson) continue;
else{
Dfs(y,y);
}
}
}
int base[D];
int LCA(int a,int b){
while(l[a].top!=l[b].top){
if(l[l[a].top].dep<l[l[b].top].dep) swap(a,b);
a=l[l[a].top].fa;
}
if(l[a].dep>l[b].dep) swap(a,b);
return a;
}
signed main(){
cin>>n>>q;
for(int i=1;i<=n;i++) {
scanf("%lld",&a[i]);
}
for(int i=1;i<n;i++){
int x,y;
scanf("%lld%lld",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,0);
Dfs(1,1);
while(q--){
int x,y;
cin>>x>>y;
int lca=LCA(x,y);
for(int i=D-1;i>=0;i--){
if(l[l[x].pos[i]].dep>=l[lca].dep) base[i]=l[x].w[i];
else base[i]=0;
}
for(int i=D-1;i>=0;i--){
if(l[l[y].pos[i]].dep>=l[lca].dep){
int Y=l[y].w[i];
for(int j=D-1;j>=0;j--){
if((Y>>j)&1){
if(base[j]) {
Y^=base[j];
}
else{
base[j]=Y;
break;
}
}
}
}
}
int ans=0;
for(int i=D-1;i>=0;i--) {
ans=max(ans,ans^base[i]);
}
cout<<ans<<"\n";
}
}
P4301 [CQOI2013] 新Nim游戏
- 题意:
给你
- 思路:
Nim 游戏其实就是看异或和,异或和不为
因为要求最小,所以要从大到小排下序。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int D=64;
ll w[D];
bool insert(ll x){
for(int i=D-1;i>=0;i--){
if((x>>i)&1){
if(w[i]){
x^=w[i];
}
else{
w[i]=x;
return true;
}
}
}
return false;
}
int n;
ll a[100004];
bool cmp(int a,int b){
return a>b;
}
ll ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
if(insert(a[i])){
continue;
}
else{
ans+=a[i];
}
}
cout<<ans;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】