首页 > 其他分享 >gym102331B Bitwise Xor

gym102331B Bitwise Xor

时间:2023-10-04 22:45:40浏览次数:35  
标签:ch Xor int void tr gym102331B Bitwise tot return

gym102331B Bitwise Xor

和我找到的题解都不同的做法。感觉简单一些。

首先将 \(a\) 排序,从高位往低位考虑,假设考虑第 \(p\) 位,不难发现这时序列按照第 \(p\) 位取值被划分为两部分,我们注意到如果 \(x\) 的这一位是 \(0\) 那么这两部分各取两个数异或起来一定满足限制,故两部分互互不影响,可以分别递归下去把方案数乘起来就是总方案数。而如果 \(x\) 的这一位是 \(1\) 那么我们根据鸽巢原理至多只能取两个数,这时候就相当于取两个数异或大于等于 \(x\),可以直接用一个 Trie 做。然后就做完了。注意复杂度不是 \(O(n \log a)\) 而是 \(O(n \log (na))\)。

const int N = 3e5 + 10;
int n;
LL x, a[N];

struct Trie {
  int ch[N * 60][2], tr[N * 60];
  int tot = 1;
  int newNode() {
    ++tot;
    tr[tot] = 0;
    ch[tot][0] = ch[tot][1] = 0;
    return tot;
  }
  void clear() {
    tot = 0; newNode();
  }
  void insert(LL x) {
    int u = 1;
    for(int i = 59; ~i; --i) {
      ++tr[u];
      int t = x >> i & 1;
      if(!ch[u][t]) ch[u][t] = newNode();
      u = ch[u][t];
    }
    ++tr[u];
  }
  int query(LL x, LL y) {
    int u = 1, res = 0;
    for(int i = 59; ~i && u; --i) {
      int t = y >> i & 1, p = x >> i & 1;
      if(t == 0) {
        res += tr[ch[u][p ^ 1]];
        u = ch[u][p];
      } else u = ch[u][p ^ 1];
    }
    return res + tr[u];
  }
}trie;

const int P = 998244353;
void add(int &x, int y) {
  (x += y) >= P ? x -= P : 0;
}
void sub(int &x, int y) {
  (x -= y) < 0 ? x += P : 0;
}

int solve(int l, int r, int p) {
  if(l > r) return 0;
  if(x >> p & 1) {
    int ans = r - l + 1;
    trie.clear();
    for(int i = l; i <= r; ++i) {
      a[i] &= (1ll << (p + 1)) - 1;
      add(ans, trie.query(a[i], x)), trie.insert(a[i]);
    }
    return ans;
  }
  int mid;
  for(mid = l; mid <= r; ++mid)
    if(a[mid] >> p & 1) break;
  return (1ll * (solve(l, mid - 1, p - 1) + 1) * (solve(mid, r, p - 1) + 1) % P - 1 + P) % P;
}

int main() {
  read(n, x);
  if(x == 0) {
    int ans = 1;
    for(int i = 1; i <= n; ++i)
      add(ans, ans);
    printf("%d\n",ans - 1);
    return 0;
  }
  for(int i = 1; i <= n; ++i)
    read(a[i]);
  sort(a + 1, a + n + 1);
  printf("%d\n",solve(1, n, 59));
}

标签:ch,Xor,int,void,tr,gym102331B,Bitwise,tot,return
From: https://www.cnblogs.com/DCH233/p/17742871.html

相关文章

  • [CF1654F] Minimal String Xoration
    MinimalStringXoration有点智慧但不是特别智慧反正是我达不到的智慧。打表可以看出长度为\(2^x\)的\(i\oplusk\)出现次数为\(2^{n-k}\)。进一步发现,设\(f(k,x)\)当前选取k时,数列前\(2^k\)的下标。则\(f(k,x)=f(k,x-1)+f(k\oplus{2^{x-1}},x-1)\)因为对于\(......
  • CF1879D Sum of XOR Functions
    异或和按位处理的典型例题。要求所有子区间异或和乘区间长度的总和,朴素的方法是\(O(n^2)\)地枚举区间,显然无法通过。因为涉及异或和,而异或运算不进位,故自然地想到把\(a_i\)写成二进制形式,单独研究每一位的贡献,最后再合并。这是处理此类问题的一般思路。1.二进制拆分比方......
  • Xor
    [ABC098D]XorSum2常规做法:发现区间缩小后肯定还是满足要求,于是双指针即可。code1非常规做法:(我的做法)我们可以发现,如果没有任何一个\(0\),那么区间长度不超过\(20\)。如何克服\(0\)?我们每个位置向右维护第一个非零的位置,然后每次跳到非零位置累加,根据最远长度计算个数。......
  • Xor-Subsequence (字典树优化DP)
     思路;明显的是,后一个i要从前面一个进行更新, 利用dpeasy版本ai<=200,发现当n>=300时,对他是没有影响的,这样比较好记录ans进行更新,利用数据结构处理hard版本拆位,利用字典树dp,把参数变成相同的参数,a[i]和i,(比大小:前K位一样第K+1位不一样......
  • Xor
    moectf{You_kn0w_h0w_t0_X0R!}XOR下载直接得到一个exe程序拖入die,64位,无壳拖入idaF5得到重点在enc数组,然后input字符串要跟其进行亦或操作,所以只要找到enc数组再将其跟0x39进行亦或便可以得到input数组(a^b=c==a^c=b)但是这里的伪代码没有enc的定义,只能在汇编代码里寻......
  • 无涯教程-JavaScript - XOR函数
    描述XOR函数返回所有参数的逻辑异或。如果所提供条件的奇数判断为TRUE,则XOR函数返回TRUE,否则返回FALSE。语法XOR(logical1,[logical2],…)争论Argument描述Required/Optionallogical1logical1isrequiredandsubsequentlogicalvaluesareoptional.1to254c......
  • F. Mahmoud and Ehab and yet another xor task 线性基
    Problem-F-Codeforces 题意:给出一个长度为n的数组,然后给出q次询问。对于每次询问,给出一个l和一个x,请你求出在[1,l]这个区间内,有多少个子序列是好的,好的的定义是这个子序列的异或和为x。做法:考虑线性基,先离线处理询问,对其l排序。然后对于l,求该情况下的线性基。然后,我们在......
  • AtCoder Beginner Contest 201 E - Xor Distances
    E-XorDistances原题链接题意:设dist(i,j)即i到j之间路径的异或和,求树上所有两点之间dist(i,j)的和思路:dist(i,j)=dist(i,1)^dist(j,1)根据异或性质相同的部分会被消掉用bfs求得dist(i,1)优化两层i,j的枚举:通过遍历每个数的每一位1的个数cnt,以及0的个数n-cnt,从而在1^0=1......
  • [CF1518D] XOR Counting
    XORCounting由于a可以为非负整数并且不关心a的具体数值,所以m大了后填很多0即可。分类讨论。m=1时直接输出n即可。m>=3时,注意到xor运算与加运算同奇偶,所以a只能异或出来与n同奇偶的数。可以构造出\(a_1=x,a_2=\frac{n-x}{2},a_3=\frac{n-x}{2},a_4=0,a......
  • CF979D Kuro and GCD and XOR and SUM
    题目大意初始有一个空的集合,和\(Q\)个操作。对于每个操作,有两种类型,分别用如下的两种形式表示:1u:加入\(u\)到集合2xks:求一个最大的\(v\),使得:\(v+x\leqs\)\(k\mid\gcd(v,x)\)\(x\oplusv\)最大(其中\(\oplus\)表示按位异或,对应C++中的^运算符)如果找不......