期望得分:100+100+40=240

实际得分:100+0+40=140

 2017北京国庆刷题Day6 afternoon

二进制拆分、二进制前缀和

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
#define N 100001
int a[N],b[N],c[N];
const int mod=1e9+7;
int suma[N][32],sumb[N][32];
int bit[31];
void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}
int finda(int r,int wh)
{
    long long tot=0;
    for(int i=0;i<=30;i++)
        if(wh&bit[i]) tot=(tot+1ll*(r-suma[r][i])*bit[i])%mod;
        else tot=(tot+1ll*suma[r][i]*bit[i])%mod;
    return int(tot%mod);
}
int findb(int r,int wh)
{
    long long tot=0;
    for(int i=0;i<=30;i++)
        if(wh&bit[i]) tot=(tot+1ll*(r-sumb[r][i])*bit[i])%mod;
        else tot=(tot+1ll*sumb[r][i]*bit[i])%mod;
    return int(tot%mod);
}
int main()
{
    freopen("xorarray.in","r",stdin);
    freopen("xorarray.out","w",stdout);
    int n;
    scanf("%d",&n);
    int len,x;
    for(int i=1;i<=n;i++) 
    {
        read(a[i]); 
        len=0; x=a[i]; 
        while(x) suma[i][len++]=suma[i-1][len]+(x&1),x/=2;
        for(int j=len;j<=30;j++) suma[i][j]=suma[i-1][j];
    }
    for(int i=1;i<=n;i++) 
    {
        read(b[i]); 
        len=0; x=b[i]; 
        while(x) sumb[i][len++]=sumb[i-1][len]+(x&1),x/=2;
        for(int j=len;j<=30;j++) sumb[i][j]=sumb[i-1][j];
    }
    bit[0]=1;
    for(int i=1;i<=30;i++) bit[i]=bit[i-1]<<1;
    c[1]=a[1]^b[1];
    for(int k=2;k<=n;k++)
    {
        c[k]=c[k-1];
        c[k]=(c[k]+finda(k-1,b[k]))%mod;
        c[k]=(c[k]+findb(k,a[k]))%mod;
    }
    for(int i=1;i<=n;i++) printf("%d ",c[i]);
}
View Code

相关文章:

  • 2021-11-13
  • 2021-07-30
  • 2021-10-25
  • 2021-12-02
  • 2022-02-13
  • 2021-10-29
  • 2021-08-19
猜你喜欢
  • 2021-10-12
  • 2022-02-04
  • 2021-07-14
  • 2021-12-11
  • 2022-02-08
  • 2021-07-30
  • 2021-11-04
相关资源
相似解决方案