QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#751057#9745. 递增序列bluejellyfishWA 0ms3912kbC++231.8kb2024-11-15 16:53:422024-11-15 16:53:45

Judging History

你现在查看的是最新测评结果

  • [2024-11-15 16:53:45]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3912kb
  • [2024-11-15 16:53:42]
  • 提交

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'