列表

详情


NC238811. 法力无边

描述

牛世界有 n 个大魔法师,第 i 个魔法师的法力值为 a_i
牛牛把他们按照编号排成了一队,他定义第 l 名法师到第 r 名法师的共同法力值 ,特别地,当 时,规定
其中 表示按位同或操作。其按位真值表如下:

a
b

0
0
1
0
1
0
1
0
0
1
1
1

注意:按位同或的操作需要指定位数 m ,不足 m 位的数在最高位补 0 ,数据保证 a_i 的位数不会超过 m
例如,当 时, ,则
而当 时, ,则
牛牛想知道 的值是多少。

输入描述

输入共两行。
第一行 2 个整数 ,含义如题。
第二行 n 个自然数,第 i 个数为 ,含义如题。

输出描述

输出共一行,为所求值。

示例1

输入:

2 1
1 1

输出:

3

说明:

指定位数为 1 时, 1\odot 1=(1)_2\odot(1)_2=(1)_2=1 ,故 M_{1,2}=1

示例2

输入:

2 2
1 1

输出:

5

说明:

指定位数为 2 时, 1\odot 1=(01)_2\odot(01)_2=(11)_2=3 ,故 M_{1,2}=3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 31ms, 内存消耗: 956K, 提交时间: 2022-10-05 21:27:52

                  #include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;

ll n,m,x,ans;
ll sum[1000020][2];

int main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&x);
		for(int j=0;j<m;j++)
		{
			if((x>>j)&1)
				sum[j][1]++;
			else
			{
				swap(sum[j][1],sum[j][0]);
				sum[j][0]++;
			}
			ans+=sum[j][1]*(1<<j); 
		}
	}
	printf("%lld",ans);
	return 0;
} 

C++(clang++ 11.0.1) 解法, 执行用时: 34ms, 内存消耗: 420K, 提交时间: 2022-10-03 11:18:39

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,x,ans,sum[100009][2];
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&x);
		for(int j=0;j<m;j++)
		{
			if((x>>j)&1)  sum[j][1]++;
			else
			{
				swap(sum[j][1],sum[j][0]);
				sum[j][0]++;
			}
			ans+=sum[j][1]*(1<<j);
		}
	}
	cout<<ans;
	return 0;
}

上一题