G69 字首線性基+貪心法 CF1100F Ivan and Burgers

董晓發表於2024-07-19

影片連結:G69 字首線性基+貪心法 CF1100F Ivan and Burgers_嗶哩嗶哩_bilibili

Ivan and Burgers - 洛谷 | 電腦科學教育新生態 (luogu.com.cn)

// 字首線性基+貪心法 O(30*n)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=500005;
int n,m,x,l,r;
int p[N][31];   //字首線性基
int pos[N][31]; //第i位的基對應數的位置

void insert(int x,int id){
  for(int i=0;i<=30;i++){ //複製前一版
    p[id][i]=p[id-1][i];
    pos[id][i]=pos[id-1][i];
  }
  int P=id;
  for(int i=30;i>=0;i--){
    if(x>>i&1){
      if(!p[id][i]){ //不存在則加入
        p[id][i]=x;
        pos[id][i]=P;
        break;
      }
      // 存在則先交換,後異或
      if(pos[id][i]<P) 
        swap(p[id][i],x),swap(pos[id][i],P);
      x^=p[id][i];
    }
  }
}
int query(int l,int r){
  int ans=0;
  for(int i=30;i>=0;i--)
    if(pos[r][i]>=l)ans=max(ans,ans^p[r][i]);
  return ans;
}
int main(){
  scanf("%d",&n);
  for(int i=1;i<=n;i++){
    scanf("%d",&x);
    insert(x,i);
  }
  scanf("%d",&m);
  while(m--){
    scanf("%d%d",&l,&r);
    printf("%d\n",query(l,r));
  }
}

// 字首線性基+貪心法 O(30*n)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=500005;
int n,m,x,l,r,a[N];
int p[N][31],pos[N][31];

void insert(int id,int p[],int pos[]){
  int x=a[id];
  for(int i=30;i>=0;i--){
    if(x>>i&1){
      if(!p[i]){ //不存在則加入
        p[i]=x;
        pos[i]=id;
        break;
      }
      // 存在則先交換,後異或
      if(pos[i]<id) swap(p[i],x),swap(pos[i],id);
      x^=p[i];
    }
  }
}
int query(int l,int r){
  int ans=0;
  for(int i=30;i>=0;i--)
    if(pos[r][i]>=l) ans=max(ans,ans^p[r][i]);
  return ans;
}
int main(){
  scanf("%d",&n);
  for(int i=1;i<=n;i++){
    scanf("%d",&a[i]);
    for(int j=0;j<=30;j++) //複製基
      p[i][j]=p[i-1][j],pos[i][j]=pos[i-1][j];    
    insert(i,p[i],pos[i]); //插入基
  }
  scanf("%d",&m);
  while(m--){
    scanf("%d%d",&l,&r);
    printf("%d\n",query(l,r));
  }
}

// 字首線性基+貪心法 O(30*n)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=500005;
int n,m,x,l,r;

struct node{
  int p[31],pos[31];
  
  void insert(node A,int x,int id){
    *this=A; //複製前一版
    for(int i=30;i>=0;i--){
      if(x>>i&1){
        if(!p[i]){ //不存在則加入
          p[i]=x;
          pos[i]=id;
          break;
        }
        // 存在則先交換,後異或
        if(pos[i]<id) swap(p[i],x),swap(pos[i],id);
        x^=p[i];
      }
    }
  }
  int query(int l){
    int ans=0;
    for(int i=30;i>=0;i--)
      if(pos[i]>=l) ans=max(ans,ans^p[i]);
    return ans;
  }
}a[N];

int main(){
  scanf("%d",&n);
  for(int i=1;i<=n;i++)
    scanf("%d",&x),a[i].insert(a[i-1],x,i);
  scanf("%d",&m);
  while(m--){
    scanf("%d%d",&l,&r);
    printf("%d\n",a[r].query(l));
  }
}

相關文章