1. 程式人生 > >HDU 3949 XOR(求異或值第k小)

HDU 3949 XOR(求異或值第k小)

題意:給定n個數,q次查詢,詢問第k小的異或值。

題目思路:線性基模板題,注意0是否可取,如果cnt==n,說明每個數對線性基都有貢獻,則不可能取到0,直接輸出第k小即可,否則要算上0。

AC程式碼:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<map>

using namespace std;

#define FOU(i,x,y) for(int i=x;i<=y;i++)
#define FOD(i,x,y) for(int i=x;i>=y;i--)
#define MEM(a,val) memset(a,val,sizeof(a))
#define PI acos(-1.0)

const double EXP = 1e-9;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const ll MINF = 0x3f3f3f3f3f3f3f3f;
const double DINF = 0xffffffffffff;
const int mod = 1e9+7;
const int N = 1e6+5;

//線性基
struct L_B{
    ll d[63],new_d[63];  //d陣列是第一次線性基,new_d是用於求Kth的線性基
    int cnt;             //記錄個數
    L_B(){
        memset(d,0,sizeof(d));
        memset(new_d,0,sizeof(new_d));
        cnt=0;
    }
    bool ins(ll val){
        for(int i=62;i>=0;i--){
            if(val&(1ll<<i)){  //存在貢獻則繼續
                if(!d[i]){     //線性基不存在,選入線性基中
                    d[i]=val;
                    break;
                }
                val^=d[i];     //否則直接改變其值
            }
        }
        return val>0;          //大於0則是成功加入線性基的向量
    }
    ll query_max(){
        ll ans=0;
        for(int i=62;i>=0;i--)
            if((ans^d[i])>ans) //能讓值變大則選入
                ans^=d[i];
        return ans;
    }
    ll query_min(){
        for(int i=0;i<=62;i++)
            if(d[i])           //最小異或值
                return d[i];
        return 0;
    }
    //以下程式碼為求第k大異或值
    void rebuild()
    {
        for(int i=62;i>=0;i--)
            for(int j=i-1;j>=0;j--)
                if (d[i]&(1LL<<j))
                    d[i]^=d[j];
        for (int i=0;i<=62;i++)
            if (d[i])
                new_d[cnt++]=d[i];
    }
    ll kthquery(int k)
    {
        ll ans=0;
        if (k>=(1ll<<cnt))
            return -1;
        for (int i=62;i>=0;i--)
            if (k&(1ll<<i))
                ans^=new_d[i];
        return ans;
    }
};

//線性基合併,暴力合併
L_B merge(const L_B &n1,const L_B &n2)
{
    L_B ret=n1;
    for (int i=62;i>=0;i--)
        if (n2.d[i])
            ret.ins(n1.d[i]);
    return ret;
}

int main()
{
    //freopen("xor_equ.in","r",stdin);
    //freopen("xor_equ.out","w",stdout);
    std::ios::sync_with_stdio(false);
    int n,t,q;
    ll x;
    scanf("%d",&t);
    int T = 0;
    while(t--){
        printf("Case #%d:\n",++T);
        scanf("%d",&n);
        L_B lb;
        for(int i=1;i<=n;i++){

            scanf("%lld",&x);
            lb.ins(x);
        }
        lb.rebuild();
        scanf("%d",&q);
        while(q--){
            scanf("%lld",&x);
            if(lb.cnt!=n){
                if(x==1)
                    printf("0\n");
                else
                    printf("%lld\n",lb.kthquery(x-1));
            }
            else
                printf("%lld\n",lb.kthquery(x));
        }
    }
    return 0;
}

相關推薦

HDU 3949 XOR求異k

題意:給定n個數,q次查詢,詢問第k小的異或值。 題目思路:線性基模板題,注意0是否可取,如果cnt==n,說明每個數對線性基都有貢獻,則不可能取到0,直接輸出第k小即可,否則要算上0。 AC程式碼: #include<cstdio> #include&

hdu3949 XOR線性基【k

題目連結 分析: 求第k大:把k二進位制拆分,如果k的第i位上是1,ans^=b[i] 這是什麼道理呢? 異或消元最後得到的是一組基 給出n個數能夠異或出來的值,都是這些基線性組合形成的數

E - Hat-Xor 的用法'^'

滴答滴答---題目連結  Statements After having a wonderful time at the Carnival test festival, Jão and his friends decided to go for an after party in

HDU 2665.Kth number-無修改區間K-可持久化線段樹(主席樹)模板

sort ota nbsp ani show 去重 第k小 math urn Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth

落谷 P3834 可持久化線段樹 1主席樹區間k

設區間為l,r,用r版本減去l版本求出區間第k小,一個板子 #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using

SDUTOJ 3307 01揹包求K

a Time Limit: 1000MS Memory limit: 65536K 題目描述 有一個奇怪的超市,超市中有m種商品,每個商品都有一個都價格pi,超市的特殊在於:如果顧客

主席樹入門詳解一學習筆記例題POJ-2104 求區間k

學習主席樹,在網上搜了很多教程(都好簡短啊,直接就是幾行字就上程式碼,看不懂啊有木有~~),最後才很艱難的學會了最基礎的部分。下面就是我在學習的過程中的產生的疑惑和解決的辦法。 學習主席樹需要的前置技能:線段樹。 參考資料 1. B站上的視訊講解(話說B站真的啥都有啊)

BestCoder Round #65 C. ZYB's Premutation線段樹求k

題意: 給定[1,i]前綴逆序對數,還原原始序列 分析: 先把前綴和還原成原來的,考慮倒著來,每個就相當於前面有多少個比自己大,線段樹求第k大就好了,BIT什麼的也可以 程式碼:

HDU-3949-XOR(線性基求K大異)

博主連結 題目連結 題意: 給你n個數,q次詢問,每次詢問在n個數組成的異或集中第K大的數 題解: 這是一個線性基裸模板題,求第k大:把k二進位制拆分,如果k的第i位上是1,ans^=nb[i] 這是什麼道理呢? 異或消元最後得到的是一組基 給出n個數能夠異或

hdu 3949 XORK

Problem Description XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A XOR B, then f

HDU 3949 XOR (k的異)

XOR Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1740    Accepted Submission

HDU 5919 - Sequence II (2016CCPC長春) 主席樹 區間K+區間不同個數

HDU 5919 題意:   動態處理一個序列的區間問題,對於一個給定序列,每次輸入區間的左端點和右端點,輸出這個區間中:每個數字第一次出現的位子留下, 輸出這些位子中最中間的那個,就是(len+1)/2那個。 思路:   主席樹操作,這裡的思路是從n到1開始建樹。其他就是主席樹查詢區間第K小,計算區

hdu 3949(線性基模版) 異和中k的數

傳送門 給定 n(n \le 10000)n(n≤10000) 個數 a_1, a_2, \ldots, a_na​1​​,a​2​​,…,a​n​​,以及 Q(Q\le 10000)Q(Q≤10000) 個詢問,每次詢問這些數(至少一個,不能不選)能夠組成的異或和

HDU 3949 XOR(線性基)

void scan one lld cstring ons ems stack utc 題意:給出一組數,求最小的第k個由這些數異或出來的數。 先求這組數的線性基。那麽最小的第k個數顯然是k的二進制數對應的線性基異或出來的數。 # include <cstdi

表達式的NOIP2011 普及組四題

兩種 可能 完成 表示 請問 字符 syn http 數字0 描述 對於 1 位二進制變量定義兩種運算:運算的優先級是:1. 先計算括號內的,再計算括號外的。2. “×”運算優先於“⊕”運算,即計算表達式時,先計算×運算,再計算⊕運算。 例如:計算表達式A⊕B × C 時,

hdu 5919--Sequence II主席樹--求區間不同數個數+區間k

positions minus -s ima date rst itl 主席樹 技術 題目鏈接 Problem Description Mr. Frog has an integer sequence of length n, which can be denot

2017 ACM-ICPC Asia Xi'an Problem A XOR線性基

problem 線段樹 all gpo efi printf 異或 bre %d 題目鏈接 2017西安賽區 Problem A 題意 給定一個數列,和$q$個詢問,每個詢問中我們可以在區間$[L, R]$中選出一些數。    假設我們選出來的這個數列為$A[i_{

hdu 3949 XOR (線性基

amp ems .cn clas bit 需要 http c++ ear 鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=3949 題意: 給出n個數,從中任意取幾個數字異或,求第k小的異或和 思路: 線性基求第k小異或和

HDU 2639 Bone Collector II0-1揹包k優解

題意: 已知物品的個數、揹包的容量、每個物品的價值和體積,求第k優解; 思路: 和0-1揹包相似,就是陣列加了多一維,不同的是對於第i個物品選和不選的問題,0-1揹包中是直接求的max(dp[j],d[j-w[i]]+v[i]);而在這裡因為要求第k優解,需要將選(mv[])和不

HDU - 3949 XOR —— 線性基

題意: 詢問給定的數列裡第k大的異或和 思路: 線性基 將所有數插入線性基之後,所有62個數有的是0,其他數最高位1的位置不相同 用類似高斯消元的方法將線性基變為每個數只有最高位1,這樣就可以方便的求出第k大的異或 最大的異或值一定是這些裡面所有數的異或(全部能為1的位置