zoukankan      html  css  js  c++  java
  • loj&codeforces 线性基

                  F. Mahmoud and Ehab and yet another xor task
    time limit per test
    1 second
    memory limit per test
    512 megabytes
    input
    standard input
    output
    standard output

    Ehab has an array a of n integers. He likes the bitwise-xor operation and he likes to bother Mahmoud so he came up with a problem. He gave Mahmoud q queries. In each of them, he gave Mahmoud 2 integers l and x, and asked him to find the number of subsequences of the first l elements of the array such that their bitwise-xor sum is x. Can you help Mahmoud answer the queries?

    A subsequence can contain elements that are not neighboring.

    Input

    The first line contains integers n and q (1 ≤ n, q ≤ 105), the number of elements in the array and the number of queries.

    The next line contains n integers a1, a2, ..., an (0 ≤ ai < 220), the elements of the array.

    The next q lines, each contains integers l and x (1 ≤ l ≤ n0 ≤ x < 220), representing the queries.

    Output

    For each query, output its answer modulo 109 + 7 in a newline.

    Examples
    input
    Copy
    5 5
    0 1 2 3 4
    4 3
    2 0
    3 7
    5 7
    5 8
    output
    4
    2
    0
    4
    0
    input
    Copy
    3 2
    1 1 1
    3 1
    2 0
    output
    4
    2
    Note

    The bitwise-xor sum of the empty set is 0 and the bitwise-xor sum of a set containing one element is that element itself.

    首先线性基有个很好的性质 对于一个数 用基地能够唯一表示 也就是说判断有多少个数异或能形成这个数  只需要确定出这个集合能异或出多少个  然后取组合数就行了  ...从而这个题就能转换成  线性基 来判断是否有解还是无解 以及这个区间能形成多少个0即可

    #include <bits/stdc++.h>
    #define ll long long
    #define s second
    #define f first
    const int mod=1e9+7;
    #define pii pair<ll,int>
    const int MAXN=1e5+10;
    using namespace std;
    ll vis[25];
    ll a[MAXN];
    vector<pii> vec[MAXN];
    ll ans[MAXN];
    ll ksm(int m){
        ll ans1=1;ll t=2;
        while(m){
            if(m&1) ans1=ans1*t%mod;
            m=m>>1;t=t*t%mod;
        }
        return ans1;
    }
    int main(){
        ios::sync_with_stdio(false);
        int n,m,l;ll x;cin>>n>>m;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=m;i++){
            cin>>l>>x;
            vec[l].push_back(make_pair(x,i));
        }
        int cnt=0;
        memset(ans,0,sizeof(ans));
        for(int i=1;i<=n;i++){
            for(int j=20;j>=0;j--){
                if((a[i]&(1<<j))){
                    if(vis[j]) a[i]^=vis[j];
                    else{
                        vis[j]=a[i];break;
                    }
                }
            }
            if(a[i]==0) cnt++;
    
            for(int j=0;j<vec[i].size();j++){
                x=vec[i][j].f;bool flag=0;
                for(int k=20;k>=0;k--){
                    if((x&(1<<k))){
                      if(vis[k]) x^=vis[k];
                      else{
                        flag=1;break;
                      }
                    }
                }
                if(!flag) ans[vec[i][j].s]=ksm(cnt);
            }
        }
        for(int i=1;i<=m;i++) cout<<ans[i]<<endl;
        return 0;
    }
    

     loj 113

    线性基模板题 ...求最大异或和 有个贪心的思想 就是说如果能从高位向地位异或 直到值不增加即可 最小值就是最低位的值

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll vis[55];ll a[55];
    int main(){
        int n;cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n;i++){
            for(int j=50;j>=0;j--){
                if(a[i]&((1ll<<j))){
                    if(vis[j]) a[i]^=vis[j];
                    else{
                        vis[j]=a[i];break;
                    }
                }
            }
        }
        ll ans=0;
        for(int i=50;i>=0;i--){
            if(!vis[i]) continue;
            if((ans^vis[i])>ans) ans^=vis[i];
        }
        cout<<ans<<endl;
        return 0;
    }
    

     loj 114

    线性基模板题  求第K小 意思可以对于线性基变形重构 成每一位只有当前位置为1 把低位用线性基异或掉 也就是说在把第k二进制分解 为1的位异或上相应的线性基即可 但是有个坑点 就是必须要考虑0的情况 特判查找即可

    #include <bits/stdc++.h>
    #define ll long long
    const int MAXN=1e5+10;
    using namespace std;
    ll vis[65],a[MAXN],d[65];int cnt;
    ll work(ll k){
        if(k>=(1ll<<cnt)) return -1;
        ll ans=0;
        for(int i=cnt-1;i>=0;i--){
            if(k&(1ll<<i)) ans^=d[i];
        }
        return ans;
    }
    int main(){
        int n;cin>>n;int flag=0;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n;i++){
            for(int j=60;j>=0;j--){
                if(a[i]&(1ll<<j)){
                    if(vis[j]) a[i]^=vis[j];
                    else{
                        vis[j]=a[i];break;
                    }
                }
            }
            if(!a[i]) flag=1;
        }
        for(int i=60;i>=0;i--){
            for(int j=i-1;j>=0;j--){
                if(vis[i]&(1ll<<j)){
                    vis[i]^=vis[j];
                }
            }
        }
        cnt=0;
        for(int i=0;i<=60;i++){
            if(vis[i]) d[cnt++]=vis[i];
        }
        int m;cin>>m;ll k;
        for(int i=1;i<=m;i++){
            cin>>k;
            if(flag) k--;
            cout<<work(k)<<endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    matplotlib 柱状图
    JavaScript 箭头函数
    JavaScript map reduce
    JavaScript sort函数
    JavaScript var、let、const
    javaScript 迭代器
    javaScript map和set
    批处理学习(-)之文件夹和文件的移动
    让 Lua 访问数据库
    lua 模块化推荐方法
  • 原文地址:https://www.cnblogs.com/wang9897/p/8719209.html
Copyright © 2011-2022 走看看