hdu3949xor(高斯消元)

看了半天題,沒想出怎麼用高斯消元解題,看完別人ac明白。
首先,用二進制去看待每一個數,因爲xor其實就是二進制的不進位加法。
比如 (十進制)2^0 2^1
1 1
2 1
3 1 1
其實3參與的xor可以用(1^2)代替,因爲1 , 2 ,3線性相關。

所以需要做的就是求出這n個數的線性無關基,這是就是可以用高斯消元,但是要求的是第幾小 ,所以希望每個消元后的數都儘量小,所以應該從高位開始消元
不理解可以看一下下邊的數據(同樣n個數不同姿勢出來的結果)

//從高位消元
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 
0
1
2
4
8
16
32
64
128
256
512
3072
9216
20480
66560
561152
//從低位開始消元
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 
0
1
2
4
8
16
32
64
128
256
512
66560
67584
73728
561152
573440
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <stack>
#include <vector>
#include <string.h>
#include <queue>
#define msc(X) memset(X,-1,sizeof(X))
#define ms(X) memset(X,0,sizeof(X))
typedef long long LL;
using namespace std;
LL a[10005];
int n;
//求第幾小應該從最高位開始消元,這樣保證了線性無關組元素和最小
void Guass(void)
{
    int max_r,col,k;
    for(k=0,col=60;k<n&&col>=0;col--)
    {
        max_r=k;
        for(int i=k+1;i<n;i++)
            if(a[i]&(1ll<<col)) {
                max_r=i;
                break;
            }
        if((a[max_r]&(1ll<<col))==0)
            continue;
        if(max_r!=k)
            swap(a[k],a[max_r]);
        for(int i=0;i<n;i++)
            if(i!=k&&(a[i]&(1ll<<col)))
                a[i]^=a[k];
        k++;
    }
    sort(a,a+n);
    n=unique(a,a+n)-a;
}
LL cal(LL k)
{
    LL ans=0;
    int i=0;
    if(a[0]==0){
        if(k==1) return 0;
        k--;
        i++;
    }
    for(;i<n&&k;k>>=1,i++)
        if(k&1)
            ans^=a[i];
    if(i==n&&k) return -1;
    return ans;
}
int main(int argc, char const *argv[])
{
    int t,ti=0;
    scanf("%d",&t);
    while(++ti<=t){
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%I64d",a+i);
        Guass();
        printf("Case #%d:\n",ti);
        int q;
        scanf("%d",&q);
        while(q--){
            LL k;
            scanf("%I64d",&k);
            printf("%I64d\n",cal(k) );
        }
    }
    return 0;
}
發佈了110 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章