1457 又是求和?

1457 又是求和?

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
题目描述 Description

给出n个整数,第i个数字为a[i],每对数字之间有一个和谐度。每对数字的和谐度定
义为这两个数字的 and,or,xor的和。而所有数的总和谐度是所有数对的和谐度
的和。现在你的任务是对于给定的n个整数,求出它们的总和谐度。

输入描述 Input Description

第一行一个整数n,表示有n个整数。
第2至n + 1行,每行有一个整数a[i],表示第i个数。

输出描述 Output Description

输出一行表示总和谐度。答案保证在263− 1以内。

样例输入 Sample Input

3
1
2
3

样例输出 Sample Output

18

数据范围及提示 Data Size & Hint

1 ≤ n ≤ 1000000,0 ≤ a[i] ≤ 30000.

分类标签 Tags 点此展开 

 
50分TLE代码:
#include<cstdio>
#define ll long long
using namespace std;
const int N=1e6+10;
inline const int read(){
    register int x=0,f=1;
    register char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,a[N];
ll tot;
int main(){
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<n;i++){
        for(int j=i+1;j<=n;j++){
            int t1=a[i]&a[j];
            int t2=a[i]|a[j];
            int t3=a[i]^a[j];
            tot+=t1+t2+t3;
        }
    }
    printf("%lld
",tot);
    return 0;
} 
题解:

首先考虑一下and,or,xor这三种运算对0,1的结果……

0 and 0=0; 0 and 1=0; 1 and 1=1;

0 xor 0=0; 0 xor 1=1; 1 xor 1=0;

0 or 0=0; 0 or 1=1; 1 or 1=1;

可以发现or的值等于and的值与xor的值之和!

显然对于二进制上的每一位如此,对整个数也是如此……因此问题转化为求两两or值之和再乘2。

求两两or值之和的问题直接考虑仍然无从下手,于是还是要按位考虑:

由于两个0或1的数取or的结果为0当且仅当两个数都是0,

因此1~n转化成二进制后每一位的两两or和就是[n(n-1)/2]-[x(x-1)/2],x为这一位为0的数有多少个

分别求出每一位的两两or和后,简单处理一下再累加就是答案。

AC代码:
#include<cstdio>
#define ll long long
using namespace std;
const int N=1e6+10;
inline const int read(){
    register int x=0,f=1;
    register char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int a[N];
ll n,x,now,ans;
int main(){
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int j=14;j+1;j--){
        now=1<<j;
        x=n;
        for(int i=1;i<=n;i++) if(a[i]&now) x--;
        ans+=(now*n*(n-1)>>1)-(now*x*(x-1)>>1);    
    }
    printf("%lld",ans<<1);
    return 0;
} 
 
原文地址:https://www.cnblogs.com/shenben/p/5924054.html