【zzuliOJ】1893 - 985的数学难题(位运算)
2016-08-03 19:48
309 查看
点击打开题目
Submit: 85 Solved: 13
SubmitStatusWeb
Board
int a[N+1];
long long Solve() {
int i, j;
long long ans = 0;
for(i = 1; i <= N; i++) {
for(int j = i + 1; j <= N; j++) {
ans += a[i] + a[j] + (a[i] ^ a[j]) + (a[i] | a[j]) + (a[i] & a[j]);
}
}
return ans;
}
注:^表示异或运算。
每组数据第一行输入一个整数代表元素个数,接下来一行输入n个正整数a[]。
注:1 <= t <= 30,1 <= n,a[] <= 100000。
依次看二进制末尾有多少数贡献了1,再根据位运算的性质进行计数即可。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
long long num[1000000];
long long ans;
bool cmp(int a,int b)
{
return a > b;
}
int main()
{
long long n;
int u;
scanf ("%d",&u);
while (u--)
{
scanf ("%lld",&n);
ans = 0;
for (int i = 1 ; i <= n ; i++)
{
scanf ("%d",&num[i]);
ans += num[i];
}
ans *= (n-1);
sort(num+1,num+1+n,cmp);
long long mul = 1;
long long ant; //二进制末尾为1的个数
while (num[1])
{
ant = 0;
for (int i = 1 ; i <= n ; i++)
{
if (num[i] == 0)
break;
if (num[i] & 1)
ant++;
num[i] >>= 1;
}
ans += (((ant-1) * ant) >> 1) * mul; //与运算
ans += ((n-ant) * ant + (((ant-1) * ant) >> 1)) * mul; //或运算
ans += ((n-ant) * ant) * mul; //异或运算
mul <<= 1;
}
printf ("%lld\n",ans);
}
return 0;
}
1893: 985的数学难题
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 85 Solved: 13
SubmitStatusWeb
Board
Description
985有n个正整数,他想快速知道下面函数的返回值int a[N+1];
long long Solve() {
int i, j;
long long ans = 0;
for(i = 1; i <= N; i++) {
for(int j = i + 1; j <= N; j++) {
ans += a[i] + a[j] + (a[i] ^ a[j]) + (a[i] | a[j]) + (a[i] & a[j]);
}
}
return ans;
}
注:^表示异或运算。
Input
第一行输入一个整数t,代表有t组测试数据。每组数据第一行输入一个整数代表元素个数,接下来一行输入n个正整数a[]。
注:1 <= t <= 30,1 <= n,a[] <= 100000。
Output
一个整数代表最后的返回值ans。Sample Input
211021 1Sample Output
04HINT
Source
hpu依次看二进制末尾有多少数贡献了1,再根据位运算的性质进行计数即可。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
long long num[1000000];
long long ans;
bool cmp(int a,int b)
{
return a > b;
}
int main()
{
long long n;
int u;
scanf ("%d",&u);
while (u--)
{
scanf ("%lld",&n);
ans = 0;
for (int i = 1 ; i <= n ; i++)
{
scanf ("%d",&num[i]);
ans += num[i];
}
ans *= (n-1);
sort(num+1,num+1+n,cmp);
long long mul = 1;
long long ant; //二进制末尾为1的个数
while (num[1])
{
ant = 0;
for (int i = 1 ; i <= n ; i++)
{
if (num[i] == 0)
break;
if (num[i] & 1)
ant++;
num[i] >>= 1;
}
ans += (((ant-1) * ant) >> 1) * mul; //与运算
ans += ((n-ant) * ant + (((ant-1) * ant) >> 1)) * mul; //或运算
ans += ((n-ant) * ant) * mul; //异或运算
mul <<= 1;
}
printf ("%lld\n",ans);
}
return 0;
}
相关文章推荐
- ZZULIOJ Problem 1893: 985的数学难题 【位运算】
- 【多校训练】ZZULIOJ 1893 985的数学难题【位运算】
- zzulioj1893: 985的数学难题(二进制计算)
- ZZULI-oj 1893: 985的数学难题(与或运算)
- zzuli 1893 (985的数学难题)
- 1893: 985的数学难题
- 1893: 985的数学难题(运算方式考察)
- 【zzuliOJ】1894 - 985的方格难题(组合数学)
- zzuli 1893 985的数学难题
- Problem B: 985的数学难题(位运算)
- 【郑轻】[1893]985的数学难题
- zzuli 1893 985的数学难题
- ZZULIOJ-1896-985的买饮料难题(水题)
- 【zzuliOJ】1895 - 985的0-1串难题(思维)
- 【zzuliOJ】1896 - 985的买饮料难题(贪心)
- ZZULIOJ-1894-985的方格难题(BFS&规律&DP)
- zzuliOJ 1894: 985的方格难题 【dp】
- zzuliOJ 1895: 985的0-1串难题 【二分】
- 【多校训练】ZZULIOJ 1894 985的方格难题
- zzulioj 1899(985的最大和难题)