Bootstrap

异或 xor

1.异或和之和(14届蓝桥省A)

先用下异或前缀和:

 此时,对于给定i的\sum_{j=i}^{n}b_{i-1}\bigoplus b_{j},在知道[i,n]某位的1、0的个数后,即可算出。

区间[i,n]某位的1或0的个数可以用前缀和预处理,这样该部分的复杂度就为O(1)了,总复杂度也降为了O(n)。

#include<bits/stdc++.h>
using namespace std;
#define int long long 

signed main()
{
    int n; 
    cin>>n;
    vector<int>a(n+1),b=a;
    vector<vector<int>>fb(n+1,vector<int>(31));//fb[i][j]即b[1]~b[i]中第j位上为1的个数
    for(int i=1;i<=n;i++){
        cin>>a[i];
        b[i]=b[i-1]^a[i];//求a的异或前缀和
        fb[i]=fb[i-1];
        for(int j=0;j<=30;j++){
            if((b[i]>>j)&1)
            fb[i][j]++;
        }
    }

    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=30;j++){
            int b1=fb[n][j]-fb[i-1][j];
            int b0=n-i+1-b1;
            if((b[i-1]>>j)&1)
            ans+=b0*(1<<j);
            else
            ans+=b1*(1<<j);
        }
    }
    cout<<ans<<endl;

}

2. Xor Sigma Problem

同样的处理方式,代码也基本一样。注意一下标的区别就行了。

#include<bits/stdc++.h>
using namespace std;
#define int long long 

signed main()
{
    int n;
    cin>>n;
    vector<int>a(n+2),b=a;
    vector<vector<int> >fb(n+2,vector<int>(31));
    for(int i=1;i<=n;i++){
        cin>>a[i];
        b[i]=b[i-1]^a[i];
        f[i]=f[i-1];
        for(int j=0;j<=30;j++){
            if((b[i]>>j)&1)
            fb[i][j]++;
        }
    }

    int ans=0;
    for(int i=0;i<=n-2;i++){
        
        for(int j=0;j<=30;j++){
            int b1=fb[n][j]-fb[i+1][j];
            int b0=n-i-1;
            if((b[i]>>1)&1)
            ans+=b0*(1<<j);
            else
            ans+=b1*(1<<j);
        }
    }
    cout<<ans;

}

3.牛客寒假营4-L

 

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long 
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
const int M=1e9+7;

signed main()
{
    ios
    int T; 
    cin>>T;
    while(T--){
        int n,q; 
        cin>>n>>q;
        vector<int>a(n+1),b=a;
        vector fa(n+1,vector<int>(31)),fb=fa;
        vector<int>f(n+2);
        for(int i=1;i<=n;i++){
            cin>>a[i];
            fa[i]=fa[i-1];
            for(int j=0;j<=30;j++)
            if(a[i]&(1<<j)) 
            fa[i][j]++;
        }
        for(int i=1;i<=n;i++){
            cin>>b[i];
            fb[i]=fb[i-1];
            for(int j=0;j<=30;j++)
            if(b[i]&(1<<j))
            fb[i][j]++;
        }
        for(int i=n;i>=1;i--){
            f[i]=f[i+1];
            for(int j=0;j<=30;j++){
                int b1=fb[n][j]-fb[i-1][j];
                int b0=(n-i+1)-b1;
                if(a[i]&(1<<j))
                f[i]+=((int)1<<j)*b0%M;
                else
                f[i]+=((int)1<<j)*b1%M;
                f[i]%=M;
            }
        }
        while(q--){
            int l,r; 
            cin>>l>>r;
            auto ans=(f[l]-f[r+1]+M)%M;
            for(int i=0;i<=30;i++){
                int a1=fa[r][i]-fa[l-1][i];
                int b1=fb[n][i]-fb[r][i];
                int a0=(r-l+1)-a1;
                int b0=(n-r)-b1;
                auto t = (int)1*a1*b0+(int)1*a0*b1;
                ans-=(t%M)*(1<<i)%M;
                ans=(ans+M)%M;
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}

 25/2/7

;