题意

题目链接

分析

  • 记操作异或和为 \(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. ionic提示弹框

    //提示框 .factory('TipsPort', function ($ionicPopup) { var TipsPort = function (tipsText, SureFunction, ...

  2. 短连接、长连接与keep-alive

    短连接与长连接 通俗来讲,浏览器和服务器每进行一次通信,就建立一次连接,任务结束就中断连接,即短连接.相反地,假如通信结束(如完成了某个HTML文件的信息获取)后保持连接则为长连接.在HTTP/1.0 ...

  3. springboot 学习之路 6(集成durid连接池)

    目录:[持续更新.....] spring 部分常用注解 spring boot 学习之路1(简单入门) spring boot 学习之路2(注解介绍) spring boot 学习之路3( 集成my ...

  4. [转] Scala 中的异步事件处理

    在任何并发性应用程序中,异步事件处理都至关重要.无论事件的来源是什么(不同的计算任务.I/O 操作或与外部系统的交互),您的代码都必须跟踪事件,协调为响应它们而执行的操作.应用程序可以采用两种基本方法 ...

  5. Linux 最小化安装后IP的配置(DHCP获取IP地址)

    图形化Linux的DHCP好配置,我就不讲了.主要将一下Linux最小化安装后IP的配置: linux最小化安装后没有ifconfig这个命令: yum install net-tools.x86_6 ...

  6. The concurrent snapshot for publication 'xxx' is not available because it has not been fully generated or the Log Reader Agent is not running to activate it

    在两台测试服务器部署了复制(发布订阅)后,发现订阅的表一直没有同步过来.重新生成过snapshot ,也重新初始化过订阅,都不能同步数据,后面检查Distributor To Subscriber H ...

  7. Android Studio连接天天模拟器

    方法:安装两者后,打开天天模拟器的adb.exe所在目录,我的是C:\Users\ Android\sdk\platform-tools,在打开的文件夹下使用“shift+鼠标右键”打开cmd终端. ...

  8. shell 在终端中打开另一个终端执行命令

    gnome-terminal -x bash -c "/home/XX/cc.sh; exec bash"

  9. June 13. 2018 Week 24th. Wednesday

    Life is too short to miss out anything; try to take it slowly. 生命短暂,放慢脚步,别错过任何沿途的风景. From Ferris Bue ...

  10. 译文——The habits of highly successful people

    1.Morning Routine (早上列行公事) Probably the most common habit ultra-successful people have is they can t ...