【題解】Luogu P2447 [SDOI2010]外星千足蟲

原題傳送門

根據題意,題目給的每一個操做就至關於異或上選中的那幾只蟲子的足數(mod 2)等於0/1

這是一個異或方程組,珂以用高斯消元解出每一個蟲子的足數(mod 2)、所需最小次數或判斷有多解

可是看題目數據範圍\(n \leq 1000,m \leq 2000\),若是直接高斯消元\(O(n^2m)\)的話超時無疑

觀察這題的個性:方程組中要經過上下行異或進行消元,這是位運算,必定珂以用bitset優化

咱們對每一行開一個bitset,這樣消元時直接把兩行的bitset異或起來,複雜度爲\(O(\frac{n^2m}{\omega})\)

#include <bits/stdc++.h>
#define N 1005 
#define M 2005
#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register int x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
inline int Max(register int x,register int y)
{
    return x>y?x:y;
}
bitset<N> b[M];
int n,m,now,ans;
int main()
{
    n=read(),m=read();
    for(register int i=1;i<=m;++i)
        for(register int j=1;j<=n+1;++j)
        {
            char ch=getchar();
            while(ch!='0'&&ch!='1')
                ch=getchar();
            b[i][j]=ch-'0';
        }
    for(register int i=1;i<=n;++i)
    {
        now=i;
        while(now<=m&&!b[now][i])
            ++now;
        if(now==m+1)
        {
            puts("Cannot Determine");
            return 0;
        }
        ans=Max(ans,now);
        if(now!=i)
            swap(b[i],b[now]);
        for(register int j=1;j<=m;++j)
        {
            if(i==j||!b[j][i])
                continue;
            b[j]^=b[i];
        }
    }
    write(ans),puts("");
    for(register int i=1;i<=n;++i)
        if(b[i][n+1])
            puts("?y7M#");
        else
            puts("Earth");
    return 0;
}
相關文章
相關標籤/搜索