QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#751057 | #9745. 递增序列 | bluejellyfish | WA | 0ms | 3912kb | C++23 | 1.8kb | 2024-11-15 16:53:42 | 2024-11-15 16:53:45 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200010;
#define ll long long
int n;
ll k;
ll a[maxn];
bool vis[66][2];
int b[66];
void miss() {
scanf("%d%lld", &n, &k);
for (int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
}
memset(vis, 0, sizeof(vis));
for (int i = 2; i <= n; ++i) {
ll x = a[i] ^ a[i-1];
for (int j = 61; j >= 0; --j) {
if (x & (1LL << j)) { // 找到第一位不同的最高位
// 此时第j位,需要和a[i-1]保持相同
vis[j][(a[i-1] >> j) & 1] = 1;
break;
}
}
}
for (int j = 61; j >= 0; --j) {
// check是否存在冲突的位置,既要求取1,又要求取0
if (vis[j][0] && vis[j][1]) {
printf("0\n");
return;
}
}
// b[i]统计从第0位到第i位,有多少位置是固定的
b[0] = vis[0][0] || vis[0][1];
for (int j = 1; j <= 61; ++j) {
b[j] = b[j-1] + (vis[j][0] || vis[j][1]);
}
ll ans = 0;
for (int j = 61; j >= 0; --j) {
ll x = k & (1LL << j);
// 该位为1,而k在该位为0
// 说明当前k的前缀,已经小于所要求的了
if (vis[j][1] && !x) {
break;
}
// k在该位为1,且该位置可以取0
// 则计算 <= k当前前缀...1xxx的所有可行的后缀解:...0xxx
// 其中xxx可以取0或者1,除掉必须取0/1的位置,剩下j-b[j-1]位
if (x && !vis[j][1]) {
ans += 1LL << (j - (j ? b[j-1] : 0));
}
// 如果该位必须取0,而k在该位为1
// 说明当前k的前缀,大于所要求的了
if (vis[j][0] && x) {
break;
}
if (j == 0) { // 特判,走到这,说明k这个数本身,符合要求
++ans;
}
}
printf("%lld\n", ans);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
cin >> T;
while(T--) miss();
//system("pause");
}
詳細信息
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 3912kb
input:
1 4 17 3 2 5 16
output:
1
result:
wrong answer 1st lines differ - expected: '4', found: '1'