cdoj第13th校赛初赛H - Hug the princess

http://acm.uestc.edu.cn/#/contest/show/54

 

H - Hug the princess

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

There is a sequence with n elements. Assuming they are a1,a2,⋯,an.
Please calculate the following expession.

In the expression above, ^ | & is bit operation.

Input

The first line contains a single integer n, which is the size of the sequence.

The second line contains n integers, the ith integer ai is the ith element of the sequence.

1n100000,0ai100000000

Output

Print the answer in one line.

Sample input and output

Sample Input Sample Output
2
1 2
6

 

 

思路:首先,自己可以通过举几个例子来验证,异或运算与与运算之和刚好等价于或运算,或者可以这样想,异或是(1,0)、(0,1),与是(1,1),合起来刚好是或。然后题目就是求两倍的或运算了。然后,每一个ai都与aj或运算(i<j),每次ai与aj或的时候,aj二进制位上是1的数位在或运算后总还是1,所以前面有多个ai与aj或,最后结果里就有多少个aj的和;然后考虑aj上是0的数位(比如第4位),记录前面所有的ai中哪些数在这个第4位上是1,记为sum[4],最后的结果里就有sum[4]*(1<<4),因为有权值的嘛。这样O(n)地扫一遍,就行了。如果就像我第一次那样直接O(n*n)地把所有数进行或运算,呵呵,tle了。

这是官方题解:

cdoj第13th校赛初赛H - Hug the princess_第1张图片

代码:

 1 #include <fstream>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <cstdlib>
 8 #include <vector>
 9 
10 using namespace std;
11 
12 #define PI acos(-1.0)
13 #define EPS 1e-10
14 #define lll __int64
15 #define ll long long
16 #define INF 0x7fffffff
17 
18 ll a[100005];
19 vector<ll> cnt;
20 
21 int main(){
22     //freopen("D:\\input.in","r",stdin);
23     //freopen("D:\\output.out","w",stdout);
24     int n;
25     ll tn=0;
26     scanf("%d",&n);
27     for(int i=0;i<n;i++){
28         scanf("%lld",&a[i]);
29         tn=max(tn,a[i]);
30     }
31     ll ans=0,t=0;
32     while(tn){
33         t++;
34         tn>>=1;
35         cnt.push_back(0);
36     }
37     for(int i=0;i<n;i++){
38         ans+=a[i]*i;
39         for(int j=0;j<t;j++){
40             if(!((a[i]>>j)&1)){
41                 ans+=(1<<j)*cnt[j];
42             }else{
43                 cnt[j]++;
44             }
45         }
46     }
47     printf("%lld\n",ans*2);
48     return 0;
49 }
View Code

 

你可能感兴趣的:(in)