题意

题目链接

分析

  • 记操作异或和为 \(tx\) ,最后一次排序时的异或和为 \(ax\) ,每个数插入时的 \(tx\) 记为 \(b\)。

  • 我们发现,一旦数列排序,就会变得容易操作。

  • 对于新加入的数字用一个前缀和数组维护每一位为 1 的个数(每个数保证在 \(xor​\) 当前 \(tx​\) 之后能够得到真实结果)。对于进行过排序的数字用 trie 维护(每个数用 \(a_i\ xor\ b_i​\) 表示)。

  • 查找 trie 上的数字在 \(xor\ ax\) 排序后的前 \(k\) 个值中每一位有多少个1,如果 \(ax\) 对应位是 1 就先走右子树。

  • 如果要进行新的排序,就将没插入 trie 的数字以 \(a_i\ xor\ b_i\) 插入到 trie 中即可。

  • 时间复杂度 \(O(nlogn)\) 。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define go(u) for(int i = head[u], v = e[i].to; i; i=e[i].lst, v=e[i].to)
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define pb push_back
#define re(x) memset(x, 0, sizeof x)
inline int gi() {
int x = 0,f = 1;
char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) { x = (x << 3) + (x << 1) + ch - 48; ch = getchar();}
return x * f;
}
template <typename T> inline bool Max(T &a, T b){return a < b ? a = b, 1 : 0;}
template <typename T> inline bool Min(T &a, T b){return a > b ? a = b, 1 : 0;}
const int N = 2e5 + 7;
int n, tp, m;
int a[N], num[N];
int ax, totx;
int f[N][33], res[33];
namespace Trie {
const int Nd = N * 33;
int ch[Nd][2], ndc = 1, son[Nd], sum[Nd][33];
void insert(int x) {
int u = 1;
for(int i = 30; ~i; --i) {
rep(j, 0, i + 1) if(x >> j & 1) ++sum[u][j];
++son[u];
int c = x >> i & 1;
if(!ch[u][c]) ch[u][c] = ++ndc;
u = ch[u][c];
}
if(x & 1)
++sum[u][0];
++son[u];
}
void query(int u, int i, int k) {
if(!u || !k || i < 0) return;
int c = ax >> i & 1;
if(son[ch[u][c]] >= k) query(ch[u][c], i - 1, k), res[i] += c * k;
else {
rep(j, 0, i) res[j] += sum[ch[u][c]][j];
query(ch[u][c ^ 1], i - 1, k - son[ch[u][c]]);
res[i] += (c ^ 1) * (k - son[ch[u][c]]);
}
}
LL query(int l, int r) {
LL ans = 0;
re(res);
query(1, 30, r);
rep(j, 0, 30)
ans += 1ll * (totx >> j & 1 ? r - res[j] : res[j]) << j; re(res);
query(1, 30, l - 1);
rep(j, 0, 30)
ans -= 1ll * (totx >> j & 1 ? l - 1 - res[j] : res[j]) << j;
return ans;
}
} LL query(int l, int r) {
LL ans = 0;
memcpy(res, f[r], sizeof res);
rep(j, 0, 30)
ans += 1ll * (totx >> j & 1 ? r - res[j] : res[j]) << j;
memcpy(res, f[l - 1], sizeof res);
rep(j, 0, 30)
ans -= 1ll * (totx >> j & 1 ? l - 1 - res[j] : res[j]) << j;
return ans;
}
int main() {
n = gi();
rep(i, 1, n) {
int x = gi();
num[++tp] = x;
rep(j, 0, 30) f[tp][j] = f[tp - 1][j] + (x >> j & 1);
}
m = gi();
while(m--) {
int opt = gi();
if(opt == 1) {
int x = gi();
num[++tp] = x ^ totx;
rep(j, 0, 30) f[tp][j] = f[tp - 1][j] + ((x ^ totx) >> j & 1);
}
if(opt == 2) {
int l = gi(), r = gi(), k = Trie::son[1];
if(r <= k)
printf("%lld\n", Trie::query(l, r));
else if(l <= k)
printf("%lld\n", query(1, r - k) + Trie::query(l, k));
else
printf("%lld\n", query(l - k, r - k));
}
if(opt == 3) {
totx ^= gi();
}
if(opt == 4) {
for(; tp; --tp) Trie::insert(num[tp]);
ax = totx;
}
}
return 0;
}

[LOJ#517]. 「LibreOJ β Round #2」计算几何瞎暴力[trie]的更多相关文章

  1. LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力

    二次联通门 : LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力 /* LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力 叫做计算几 ...

  2. 「LibreOJ β Round #2」计算几何瞎暴力

    https://loj.ac/problem/517 题解 首先我们如果没有排序这个骚操作的话,可以直接记一下各个数位的前缀和,然后异或标记给全局打,查询的时候先把区间信息提取出来然后整体异或就好了. ...

  3. [LOJ#531]「LibreOJ β Round #5」游戏

    [LOJ#531]「LibreOJ β Round #5」游戏 试题描述 LCR 三分钟就解决了问题,她自信地输入了结果-- > -- 正在检查程序 -- > -- 检查通过,正在评估智商 ...

  4. [LOJ#530]「LibreOJ β Round #5」最小倍数

    [LOJ#530]「LibreOJ β Round #5」最小倍数 试题描述 第二天,LCR 终于启动了备份存储器,准备上传数据时,却没有找到熟悉的文件资源,取而代之的是而屏幕上显示的一段话: 您的文 ...

  5. [LOJ#516]「LibreOJ β Round #2」DP 一般看规律

    [LOJ#516]「LibreOJ β Round #2」DP 一般看规律 试题描述 给定一个长度为 \(n\) 的序列 \(a\),一共有 \(m\) 个操作. 每次操作的内容为:给定 \(x,y\ ...

  6. [LOJ#515]「LibreOJ β Round #2」贪心只能过样例

    [LOJ#515]「LibreOJ β Round #2」贪心只能过样例 试题描述 一共有 \(n\) 个数,第 \(i\) 个数 \(x_i\) 可以取 \([a_i , b_i]\) 中任意值. ...

  7. [LOJ#525]「LibreOJ β Round #4」多项式

    [LOJ#525]「LibreOJ β Round #4」多项式 试题描述 给定一个正整数 k,你需要寻找一个系数均为 0 到 k−1 之间的非零多项式 f(x),满足对于任意整数 x 均有 f(x) ...

  8. [LOJ#526]「LibreOJ β Round #4」子集

    [LOJ#526]「LibreOJ β Round #4」子集 试题描述 qmqmqm有一个长为 n 的数列 a1,a2,……,an,你需要选择集合{1,2,……,n}的一个子集,使得这个子集中任意两 ...

  9. [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)

    [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 …… 接着他们发现自己收 ...

随机推荐

  1. vue 构建项目 文件引入

    1.vue引用依赖文件.  举例:axios 先安装 axios.如果直接安装 vue-axios 会报错 npm install axios npm install --save axios vue ...

  2. Android view层

    当屏幕可以装下内容的时候,他们的值相等,只有当view超出屏幕后,才能看出他们的区别:getMeasuredHeight()是实际View的大小,与屏幕无关,而getHeight的大小此时则是屏幕的大 ...

  3. JS 调试中常见的报错的解决办法

    报错:Uncaught SyntaxError: Unexpected token o in JSON at position 1 at JSON.parse (<anonymous>) ...

  4. Python random模块方法

    random内置模块中的方法注解 random.seed(a=None, version=2) # 初始化伪随机数生成器,若种子a相同,则可以使生成的随机数相同.如果未提供a或者a=None,则使用系 ...

  5. 网络互联技术(2)——前篇—【转载】电脑结构和CPU、内存、硬盘三者之间的关系

    原文链接:传送门 详细内容: 电脑结构和CPU.内存.硬盘三者之间的关系 前面提到了,电脑之父——冯·诺伊曼提出了计算机的五大部件:输入设备.输出设备.存储器.运算器和控制器. 我们看一下现在我们电脑 ...

  6. AngularJS学习之旅—AngularJS 表达式(二)

    1.AngularJS 表达式 AngularJS 表达式写在双大括号内:{{ expression }}. AngularJS 表达式把数据绑定到 HTML,这与 ng-bind 指令有异曲同工之妙 ...

  7. 常用的几条sql语句

    ### 常用的几条sql语句 选择:select * from table1 where 范围 插入:insert into table1(field1,field2) values(value1,v ...

  8. 聚类——WKFCM

    聚类——认识WKFCM算法 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 参考文献:Shen H, Yang J, Wang S, et al. At ...

  9. [福大软工] Z班 团队第一次作业—团队展示成绩公布

    [福大软工] Z班 团队第一次作业-团队展示成绩公布 作业地址 http://www.cnblogs.com/easteast/p/7511264.html 作业要求 队员姓名与学号(标记组长),其中 ...

  10. spring的基于XML方式的属性注入

    1.掌握spring的属性注入的方法: 1.1构造方法注入普通值---------<constructor-arg>标签的使用 首先新建一个类 package spring.day1.de ...