线性基
题目链接:
http://47.96.116.66/problem.php?id=1829
#include<bits/stdc++.h> #define fi first #define se second #define INF 0x3f3f3f3f #define LNF 0x3f3f3f3f3f3f3f3f #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define pqueue priority_queue #define NEW(a,b) memset(a,b,sizeof(a)) #define lowbit(x) (x&(-x)) #define si(x) scanf("%d",&x) #define sl(x) scanf("%lld",&x) #define lc (d<<1) #define rc (d<<1|1) const double pi=4.0*atan(1.0); const double e=exp(1.0); const int maxn=1e6+8; typedef long long LL; typedef unsigned long long ULL; using namespace std; int n; LL a[maxn],p[108][67],b[108]; LL dp[108][108]; void get(int n){ for(int i=1;i<=n;i++){ for(int j=62;j>=0;j--) p[i][j]=p[i-1][j]; for(int j=62;j>=0;j--){ if(!(a[i]>>j)) continue;//对线性基的这一位没有贡献 if(!p[i][j]) { p[i][j]=a[i]; break; }//选入线性基中 a[i]^=p[i][j]; } } } int main(){ fio; while(cin>>n){ for(int i=1;i<=n;i++){ cin>>a[i]; b[i]=a[i]; } memset(p,0,sizeof(p)); get(n); memset(dp,LNF,sizeof(dp)); dp[1][1]=b[1]; for(int i=2;i<=n;i++){ LL s=b[i],y=b[i],ty; for(int j=62;j>=0;j--) s=max(s,s^p[i-1][j]),y=min(y,y^p[i-1][j]); dp[i][1]=min(dp[i-1][1],y);ty=s; for(int j=2;j<=i;j++){ s=ty; for(int k=62;k>=0;k--) { if((s^p[i-1][k])>=s) continue; if((s^p[i-1][k])>dp[i-1][j-1]) s^=p[i-1][k]; else { LL zz=s^p[i-1][k]; for(int kk=k-1;kk>=0;kk--) zz=max(zz,zz^p[i-1][kk]); if(zz>dp[i-1][j-1]) s=zz; } } if(s<=dp[i-1][j-1]) s=LNF; dp[i][j]=min(dp[i-1][j],s); } } for(int j=n;j>=1;j--) if(dp[n][j]!=LNF) {cout<<j<<endl;break;} } }