Mahmoud and Ehab and yet another xor task

Mahmoud and Ehab and yet another xor task

解题思路:先离线处理,按照l从小到大排序。然后依次将a数组中的数插入到线性基中,如果个数达到了l,判断x是否可以由线性基中的数异或得到。如果能那么答案就是2l-cnt,l表示已经插入了多少个数,cnt表示线性基中有几个非0的数。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double lf;
typedef unsigned long long ull;
typedef pair<int,int>P;
const int inf = 0x7f7f7f7f;
const double INF = 1e16;
const int N = 1e5+7;
const ll mod = 1e9+7;
const double PI = 3.1415926535;
const double eps = 1e-4;

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
inline string readstring(){
    string str;char s=getchar();while(s==' '||s=='\n'||s=='\r'){s=getchar();}while(s!=' '&&s!='\n'&&s!='\r'){str+=s;s=getchar();}return str;
}
int random(int n){
    return (int)(rand()*rand())%n;
}

ll a[N];
ll b[100];
ll ans[N];
struct node{
    int id;
    int l;
    ll x;
}c[N];

bool cmp(node a,node b){
    return a.l < b.l;
}
void Insert(ll x){
    for(int i = 63;i >= 0;i--){
        if(x&(1ll<<i)){
            if(b[i]) x ^= b[i];
            else {
                b[i] = x;
                break;
            }
        }
    }
}
bool check(ll x){
    for(int i = 63;i >= 0;i--){
        if(x&(1ll<<i)){
            if(b[i]) x ^= b[i];
            else {
                return false;
            }
        }
    }
    return true;
}
int fun(){
    int ret = 0;
    for(int i = 63;i >= 0;i--){
        if(b[i]) ret++;
    }
    return ret;
}

ll funn(int cnt){
    ll ans = 1;
    ll a = 2ll;
    if(cnt < 0) return ans;
    while(cnt){
        if(cnt&1) ans = (ans*a)%mod;
        a = (a*a)%mod;
        cnt >>= 1;
    }
    return ans;
}
int main(){
//    srand((unsigned)time(NULL));
    int n = read(),q = read();
    for(int i = 1;i <= n;i++){
        cin >> a[i];
    }
    for(int i = 1;i <= q;i++){
        c[i].id = i;
        cin >> c[i].l>> c[i].x;
    }
    sort(c+1,c+1+q,cmp);
    int k = 1;
    for(int i = 1;i <= n;i++){
        Insert(a[i]);
        while(k <= q && c[k].l == i){
            if(check(c[k].x)){
                int p = i-fun();
                ans[c[k].id] = funn(p);
            }
            k++;
        }
    }
    for(int i = 1;i <= q;i++){
        cout<<ans[i]<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42868863/article/details/113100988