• CQUOJ 9884 Dima and Sequence


    Dima got into number sequences. Now he's got sequence a1, a2, ..., an, consisting of n positive integers. Also, Dima has got a function f(x), which can be defined with the following recurrence:

    • f(0) = 0;
    • f(2·x) = f(x);
    • f(2·x + 1) = f(x) + 1.

    Dima wonders, how many pairs of indexes (i, j) (1 ≤ i < j ≤ n) are there, such that f(ai) = f(aj). Help him, count the number of such pairs.

     

    Input

    The first line contains integer n (1 ≤ n ≤ 105). The second line contains n positive integers a1, a2, ..., an (1 ≤ ai ≤ 109).

    The numbers in the lines are separated by single spaces.

     

    Output

    In a single line print the answer to the problem.

    Please, don't use the %lld specifier to read or write 64-bit integers in C++. It is preferred to use the cin, cout streams or the%I64d specifier.

     

    Sample Input

    Input
    3
    1 2 4
    Output
    3
    Input
    3
    5 3 1
    Output
    1

    Hint

    In the first sample any pair (i, j) will do, so the answer is 3.

    In the second sample only pair (1, 2) will do.

     1 /*
     2 2016年4月24日15:54:49
     3 
     4 分析过程:
     5 如果是偶数,那么直接等于除以2,如:  f(8) = f(4) = f(2) = f(1)
     6 如果是奇数,那么直接等于除以2之后在加1,
     7     如:f(19) = f(9) + 1 = f(4) + 2 = f(2) + 2 = f(1) + 2 = f(0) + 3 = 3 
     8 可以证明,左右数字都能经过不断地除以2,最后得到式子:f(0) + x = x 
     9 第一、通过观察可知,只要是比1大的数,经过不断除以2,最后都能得到1,不管是奇数还是偶数
    10 第二、通过公式可知,如果是偶数,就是像是8,它除以2之后,并不会增加x的值,
    11     只有奇数除以2之后,会把余出的1加在函数f外面的x上 
    12 
    13 所以,问题的关键在于:在原来的除以直到除得0为止,一共有多少个商是奇数(包括原数在内)
    14 然后得到一个值 k, num[k]   表示 所给的n个数中 值是k的个数 
    15 最后只要看经过计算后的数列中,每个数字出现的次数,
    16 通过排列组合(C n 2  你懂得...),计算出有多少对相同的数对 
    17 
    18 */
    19 # include <iostream>
    20 # include <cstdio>
    21 # include <cstring>
    22 # include <algorithm>
    23 # include <queue>
    24 # include <vector>
    25 # include <cmath>
    26 # define LL long long 
    27 # define INF 0x3f3f3f3f
    28 using namespace std;
    29 const int N = 1e5 + 5;
    30 LL num[34];  
    31 //  题目给的 a 最大不超过 1e9  即就算它二进制数上全是1  k值也不超过 32 
    32 //   若 a = 63   二进制数为 0000111111   k = 6 ......
    33 
    34 int main(void)
    35 {
    36     int n, i, a;
    37     LL ans, k;
    38     while (~scanf("%d", &n))
    39     {
    40         memset(num, 0, sizeof(num));
    41         for (i = 1; i <= n; i++){
    42             scanf("%d", &a);
    43             k = 0;
    44             while (a){
    45                 if (a % 2 == 1) k++;
    46                 a >>= 1;
    47             }
    48             num[k]++;
    49         }
    50         ans = 0;
    51         for (i = 1; i < 34; i++){
    52             ans += num[i] * (num[i]-1) / 2;
    53         }
    54         printf("%I64d
    ", ans);
    55     } 
    56     
    57     return 0;    
    58 }
  • 相关阅读:
    一个整型数组里除了两个数字之外,其他的数字都出现了两次
    输入一颗二叉树的根节点,求该树的深度
    输入两个单向链表,找出它们的第一个公共结点
    java归并排序
    这样设计 Java 异常更优雅,赶紧学!
    2019 最新 Java 核心技术教程,都在这了!
    程序员加班写的代码,千万不要相信!
    为什么有些大公司技术弱爆了?
    这才是微服务划分的正确姿势,值得学习!
    为什么 Kafka 速度那么快?
  • 原文地址:https://www.cnblogs.com/hyq123456/p/5427708.html
Copyright © 2020-2023  润新知