UESTC--1041--Hug the princess(位运算)



Hug the princess

Time Limit: 1000MS   Memory Limit: 65535KB   64bit IO Format: %lld & %llu

Submit Status

Description

There is a sequence with n elements.
Assuming they are a1,a2,?,an.

Please calculate the following expession.

∑1≤i<j≤n(ai∧aj)+(ai|aj)+(ai&aj)

In the expression above, ^|& is bit operation. If you don’t know bit operation, you can visit

http://en.wikipedia.org/wiki/Bitwise_operation

to get some useful information.

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.

1≤n≤100000,0≤ai≤100000000

Output

Print the answer in one line.

Sample Input

2

1 2

Sample Output

6

Hint

Because the answer is so large, please use long long instead of int. Correspondingly, please use %lld instead of %d to scanf and printf.

Large input. You may get Time Limit Exceeded if you use “cin” to get the input. So “scanf” is suggested.

Likewise, you are supposed to use “printf” instead of “cout”.

Source

The 13th UESTC Programming Contest Preliminary

n个数,然后每个数对他后边的数字进行所有的位运算,然后取这些位运算的和,因为数的个数太多,所以不能直接暴力,所以这一步把数字转化为2进制,然后记录前缀和,并且记录每个数的最高位,同时对他下边的二进制位进行染色,表示这一位有多少个数字可以影响到,最后根据位运算的规则,对后边的前缀和操作,因为我们已经记录了每一个数对一个二进制位的影响,所以可以分清1还有0都是谁的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1e5 + 100;
int num[MAXN][35];
int a[35];
int p[MAXN];
typedef long long LL;
int main()
{
	int n;
	while(~scanf("%d", &n))
	{
		int x;
		memset(num, 0, sizeof(num));
		for(int i = 1; i <= n; i++)
		{
			scanf("%d", &x);
			for(int j = 0; j < 33; j++)
			{
				num[i][j] = num[i - 1][j] + x % 2;
				x = x / 2;
			}
		}
		LL ans = 0;
		for(int i = 1; i <= n; i++)
		{
			int temp = 0, pos = -1;
			for(int j = 0; j < 33; j++)
			{
				a[j] = num[i][j] - num[i - 1][j];
			}
			for(int j = 0; j < 33; j++)
			{
				int cnt = 0;
				if(a[j])
				{
					cnt += (i - 1 - num[i - 1][j]);
					cnt += i - 1;
					cnt += num[i - 1][j];
				}
				else
				{
					cnt += num[i - 1][j];
					cnt += num[i - 1][j];
				}
				ans += (LL)cnt * (1 << j);
			}
		}
		printf("%lld\n", ans);
	}
	return 0;
}
时间: 2024-10-24 04:09:55

UESTC--1041--Hug the princess(位运算)的相关文章

Hug the princess(思维,位运算)

Hug the princess Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status There is a sequence with nn elements. Assuming they are a1,a2,?,ana1,a2,?,an. Please calculate the following expession. ∑1≤i<j≤n(ai∧aj)

位运算

位运算的实际应用场景 http://blog.csdn.net/zmazon/article/details/8262185

POJ 1781 In Danger Joseph环 位运算解法

Joseph环,这次模固定是2.假设不是固定模2,那么一般时间效率是O(n).可是这次由于固定模2,那么能够利用2的特殊性,把时间效率提高到O(1). 规律能够看下图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2VuZGVuMjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" > 具体具体解析请看大师Knuth的Concrete m

位运算总结&amp;拾遗

JavaScript 位运算总结&拾遗 最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个数为2的幂,那么该数的二进制码只有最高位是1. 根据这个性质,我们来举个栗子,比如有数字10,转为二进制码后为: 1 0 1 0 我们只需把 0 bit的位置全部用1填充,然后再把该二进制码加1就ok了.而x | (x + 1)正好可以把最右边的0置为1,可是

Java I/O : Bit Operation 位运算

Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter    :BYSocket 泥瓦匠喜欢Java,文章总是扯扯Java. I/O 基础,就是二进制,也就是Bit. 一.Bit与二进制 什么是Bit(位)呢?位是CPU处理或者数据存储最小的单元.类似于很小很小的开关,一开一关,表示为1或者0.所以,这就是计算机处理任何数据的"细胞",要谨记.

mysql位运算

1.MOD(X1,X2) 求余运算,返回余数同"%" 2.X1 DIV X2 除法运算返回商,同"/" 3.如果除数为0,那么结果为NULL. 4.<=>和= 是一样的,也是用来判断操作数是否相等的.不同的是<=>可以用来判断null,=不能判断null. 例:select null<=>null 结果1 逻辑运算符 1.与&&或and:所有操作数不为0且不为null时,结果为1,任何一操作数为0,结果为0,存在一

位运算之 C 与或非异或

位运算比较易混: 位运算之 C 与或非异或 与运算:& 两者都为1为1,否则为0 1&1=1,  1&0=0,  0&1=0,  0&0=0 或运算:| 两者都为0为0,否则为1 1|1 = 1,  1|0 = 1,  0|1 = 1, 0|0 = 0 非运算:~ 1取0,0取1 ~1 = 0, ~0 = 1 ~(10001) = 01110 异或运算:^ 两者相等为0,不等为1(易混淆) 1^1=0, 1^0=1, 0^1=1, 0^0=0 位移操作符:<&

Java的位运算

左移位操作 左移位运算的符号为[<<],左移位运算符左面的操作元称作被移位数,右面的操作数称作移位量. 左移位运算是双目运算符,操作元必须是整型类型的数据,其移动过程是:[a << n]运算的过程是通过将a的所有位都左移n位,每左移一个位,左边的最高位上的0或1被移出丢弃,并用0填充右边的低位 注意: 如果a是byte.short或int型数据,总是先计算出n%32的结果m,然后进行a<<m运算 对于long型数据,总是先计算出n%64的结果m,然后进行a <&l

常见的位运算

位运算主要有:|   &   ^    ~ & 这个是只要有0,则0 | 这个只要有1,则1 ^异或运算,只要不同则为1 ~全部相反 参与位运算首先要将数值化作为二进制补码,方可参与运算 >>                                               >>>                                << 有符号右移                                无符号右移