使用 ``1ll<<(N-1)`` 将大量值分配给 long long int 变量
using ``1ll<<(N-1)`` to assign a large number of value to a long long int variable
我看到的问题是这样写的:给你一个大小为N的数组A。如果元素 Ai 的值 (Ai) 大于或等于 Ki[=30=,则称该元素带电] 和 Ki 是包含元素 Ai 的数组 A 的子集总数。
逻辑很简单,一个数字作为子集出现的次数是2^N-1次。但在某些测试用例中,N 为 4000+。因此,2^N-1 将超出任何变量类型所能容纳的范围,但在编辑中,作者使用了 1ll<<(N-1)
。我知道左移运算符是 X<<Y = X*2^Y
。但是这个 1ll 是什么?它是如何存储如此大的价值的?
#include <bits/stdc++.h>
#define M 1000000007
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int T;
cin >> T;
while (T--) {
int N;
cin >> N;
long long arr[N];
for (int i = 0; i < N; i++)
cin >> arr[i];
if (N >= 64)
cout << 0 << endl;
else {
long long val = (1ll << (N - 1));
long long ans = 0;
for (int i = 0; i < N; i++)
if (arr[i] >= val)
ans = (ans + arr[i] % M) % M;
cout << ans << endl;
}
}
}
1<<N-1
解释了 2^N-1 但是 1ll 是否意味着它可能需要 long long 和 long long val = 1ll<<N-1
;意味着它可以达到 128 位?
But what is this 1ll
?
1ll
是一个 integer literal。 1
是一个 十进制文字 而 ll
是一个 整数后缀 。后缀ll
表示整数字面量的类型是long long int
。 1
意味着文字的值是 1
.
And how is it able to store such large value?
我想你问的是这条线:
long long val = (1ll << (N - 1));
因为之前的if (N >= 64) .. else
,我们知道N < 64
。所以最大数量可以是:
1ll << 63 - 1 =
1ll << 62 =
0x4000000000000000
这只是一个适合 long long int
类型的数字。 long long int
类型至少有 64 位。
如果没有 ll
后缀,1
的类型将是 int
。在 int
类型比 64 位窄的体系结构上,例如。 16 位,然后会发生未定义的行为。将变量左移一个大于或等于左操作数位长度的数字是未定义的行为,请参见 ex。 this question.
如果你问的是这条线:
ans = (ans + arr[i] % M) % M;
正在计算求和模#define M 1000000007
。通常做 assignments/homework 计算和模这个数字,见前 this or this。该算法计算总和模 1000000007,而不是整数,这就是它能够将其存储在 long long
变量中的原因。
我看到的问题是这样写的:给你一个大小为N的数组A。如果元素 Ai 的值 (Ai) 大于或等于 Ki[=30=,则称该元素带电] 和 Ki 是包含元素 Ai 的数组 A 的子集总数。
逻辑很简单,一个数字作为子集出现的次数是2^N-1次。但在某些测试用例中,N 为 4000+。因此,2^N-1 将超出任何变量类型所能容纳的范围,但在编辑中,作者使用了 1ll<<(N-1)
。我知道左移运算符是 X<<Y = X*2^Y
。但是这个 1ll 是什么?它是如何存储如此大的价值的?
#include <bits/stdc++.h>
#define M 1000000007
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int T;
cin >> T;
while (T--) {
int N;
cin >> N;
long long arr[N];
for (int i = 0; i < N; i++)
cin >> arr[i];
if (N >= 64)
cout << 0 << endl;
else {
long long val = (1ll << (N - 1));
long long ans = 0;
for (int i = 0; i < N; i++)
if (arr[i] >= val)
ans = (ans + arr[i] % M) % M;
cout << ans << endl;
}
}
}
1<<N-1
解释了 2^N-1 但是 1ll 是否意味着它可能需要 long long 和 long long val = 1ll<<N-1
;意味着它可以达到 128 位?
But what is this
1ll
?
1ll
是一个 integer literal。 1
是一个 十进制文字 而 ll
是一个 整数后缀 。后缀ll
表示整数字面量的类型是long long int
。 1
意味着文字的值是 1
.
And how is it able to store such large value?
我想你问的是这条线:
long long val = (1ll << (N - 1));
因为之前的if (N >= 64) .. else
,我们知道N < 64
。所以最大数量可以是:
1ll << 63 - 1 =
1ll << 62 =
0x4000000000000000
这只是一个适合 long long int
类型的数字。 long long int
类型至少有 64 位。
如果没有 ll
后缀,1
的类型将是 int
。在 int
类型比 64 位窄的体系结构上,例如。 16 位,然后会发生未定义的行为。将变量左移一个大于或等于左操作数位长度的数字是未定义的行为,请参见 ex。 this question.
如果你问的是这条线:
ans = (ans + arr[i] % M) % M;
正在计算求和模#define M 1000000007
。通常做 assignments/homework 计算和模这个数字,见前 this or this。该算法计算总和模 1000000007,而不是整数,这就是它能够将其存储在 long long
变量中的原因。