zoukankan      html  css  js  c++  java
  • 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;
    } 
     
  • 相关阅读:
    zabbix源码安装
    利用Linux系统生成随机密码的8种方法
    Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结
    Jenkins的参数化构建
    Jenkins中maven的作用--构建项目(三)
    Beans(dp,两次dp)
    Piggy-Bank(完全背包)
    Super Jumping! Jumping! Jumping!(dp)
    01串(dp)
    钱币兑换问题(完全背包)
  • 原文地址:https://www.cnblogs.com/shenben/p/5924054.html
Copyright © 2011-2022 走看看