题目链接

BZOJ4103

题解

一眼看过去是二维结构,实则未然需要树套树之类的数据结构

区域异或和,就一定是可持久化\(trie\)树

观察数据,\(m\)非常大,而\(n\)和\(p\)比较小,甚至可以每次询问都枚举\(x_i\)

所以我们可以考虑对\(y_i\)建\(trie\),每次询问取出对应区间的\(x_i\)在对应区间的\(trie\)树中跑

多点询问和单点询问时类似的,只不过它们会分开走

我们只需每次记录每个\(x_i\)所在的节点

对于每一层,统计一下能异或出多少\(1\),如果\(\le k\),每个\(x_i\)往能异或出\(1\)的方向走,否则走另一边,并令\(k\)减去这些数

复杂度\(O(31m + 31qn)\)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 300005,B = 30,maxm = 10000005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int bin[50],n,m;
int a[1005],b[maxn],rt[maxn],cnt;
int ch[maxm][2],sum[maxm];
int ins(int x,int v){
int u,tmp;
u = tmp = ++cnt;
for (int i = B; ~i; i--){
ch[u][0] = ch[v][0];
ch[u][1] = ch[v][1];
sum[u] = sum[v] + 1;
int t = bin[i] & x; t >>= i;
v = ch[v][t];
u = ch[u][t] = ++cnt;
}
sum[u] = sum[v] + 1;
return tmp;
}
int atu[1005],atv[1005];
int query(int u,int v,int l,int r,int k){
int ans = 0;
for (int i = l; i <= r; i++) atu[i] = u,atv[i] = v;
for (int i = B; ~i; i--){
int cnt = 0;
for (int j = l; j <= r; j++){
int x = atu[j],y = atv[j],t = bin[i] & a[j]; t >>= i;
cnt += sum[ch[x][t ^ 1]] - sum[ch[y][t ^ 1]];
}
if (cnt >= k){
ans += bin[i];
for (int j = l; j <= r; j++){
int x = atu[j],y = atv[j],t = bin[i] & a[j]; t >>= i;
atu[j] = ch[x][t ^ 1];
atv[j] = ch[y][t ^ 1];
}
}
else {
k -= cnt;
for (int j = l; j <= r; j++){
int x = atu[j],y = atv[j],t = bin[i] & a[j]; t >>= i;
atu[j] = ch[x][t];
atv[j] = ch[y][t];
}
}
}
return ans;
}
int main(){
bin[0] = 1; for (int i = 1; i <= 30; i++) bin[i] = bin[i - 1] << 1;
n = read(); m = read();
for (int i = 1; i <= n; i++) a[i] = read();
for (int i = 1; i <= m; i++){
b[i] = read();
rt[i] = ins(b[i],rt[i - 1]);
}
int p = read(),u,d,l,r,k;
while (p--){
u = read(); d = read(); l = read(); r = read(); k = read();
printf("%d\n",query(rt[r],rt[l - 1],u,d,k));
}
return 0;
}

BZOJ4103 [Thu Summer Camp 2015]异或运算 【可持久化trie树】的更多相关文章

  1. [BZOJ4103][Thu Summer Camp 2015]异或运算 可持久化Trie树

    4103: [Thu Summer Camp 2015]异或运算 Time Limit: 20 Sec  Memory Limit: 512 MB Description 给定长度为n的数列X={x1 ...

  2. 【bzoj4103】[Thu Summer Camp 2015]异或运算 可持久化trie树

    Description 给定长度为n的数列X={x1,x2,...,xn}和长度为m的数列Y={y1,y2,...,ym},令矩阵A中第i行第j列的值Aij=xi xor yj,每次询问给定矩形区域i ...

  3. BZOJ 4103: [Thu Summer Camp 2015]异或运算 可持久化trie

    开始想了一个二分+可持久化trie验证,比正解多一个 log 仔细思考,你发现你可以直接按位枚举,然后在可持久化 trie 上二分就好了. code: #include <bits/stdc++ ...

  4. bzoj4103 [Thu Summer Camp 2015]异或运算(可持久化trie)

    内存限制:512 MiB 时间限制:1000 ms 题目描述 给定长度为n的数列X={x1,x2,...,xn}和长度为m的数列Y={y1,y2,...,ym},令矩阵A中第i行第j列的值Aij=xi ...

  5. bzoj4103: [Thu Summer Camp 2015]异或运算

    对于每个询问暴力枚举x~y,然后在Trie去找第k大,开始我写了个二分答案然后算比当前答案大的个数,打了个第10个点的表就跑出19s+比bzoj垫底还慢4s+ 然而不用二分,直接1000个点一起在树上 ...

  6. 【BZOJ 4103】 [Thu Summer Camp 2015]异或运算 可持久化01Trie

    我们观察数据:树套树 PASS    主席树 PASS  一层一个Trie PASS 再看,异或!我们就把目光暂时定在01Tire然后我们发现,我们可以带着一堆点在01Trie上行走,因为O(n*q* ...

  7. 【BZOJ 4103】 4103: [Thu Summer Camp 2015]异或运算 (可持久化Trie)

    4103: [Thu Summer Camp 2015]异或运算 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 474  Solved: 258 De ...

  8. [BZOJ 4103] [Thu Summer Camp 2015] 异或运算 【可持久化Trie】

    题目链接:BZOJ - 4103 题目分析 THUSC滚粗之后一直没有写这道题,从来没写过可持久化Trie,发现其实和可持久化线段树都是一样的.嗯,有些东西就是明白得太晚. 首先Orz ZYF-ZYF ...

  9. [十二省联考2019]异或粽子——可持久化trie树+堆

    题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...

随机推荐

  1. docker in docker

    docker run --rm可以从一个镜像启动容器,并在容器执行完成后自动删除,这在计算任务中非常有用. 例如,我们通过以下步骤完成计算任务容器的启动: 1 将输入数据通过卷挂载方式连接到计算任务容 ...

  2. 打造移动应用与游戏安全防线,腾讯WeTest安全服务全线升级

    当移动互联网渗透到千家万户,与工业控制.智慧交通.实时社交.休闲娱乐紧密结合时,应用安全就变得尤为重要. 尤其在网络强相关的APP流行年代,当APP应用客户端上传与获取信息,大多通过接口在服务器双向通 ...

  3. hdu1159Common Subsequence(动态规划)

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. Linux命令应用大词典-第19章 文件系统管理

    19.1 mkfs:创建Linux文件系统 19.2 mke2fs:创建ext2.3.4文件系统 19.3 mkfs.ext4:创建ext4文件系统 19.4 mkfs.ext3:创建ext3文件系统 ...

  5. Objective-C 内存管理和ARC

    内存管理 范围: 任何继承了NSObject的对象 对基本数据类型无效 原理: 每个对象内部都保存了一个与之相关联的整数 称为引用计数器 1.计数器的基本操作 当使用alloc new或者copy创建 ...

  6. 【springmvc+mybatis项目实战】杰信商贸-5.生产厂家DAO+SERVICE+CONTROLLER+JSP+配置文件

    上一篇我们创建了工程和一个Factory的po对象(javaBean),我们也写好了Mapper的映射文件,接下来我们来完成生产厂家的DAO与SERVICE,以及CONTROLLER,还有做显示的JS ...

  7. 《Git学习指南》学习笔记(一)

    第二章 入门 git的安装 在Linux下,git的安装很简单.以我的系统Deepin/Ubuntu为例,只需在终端敲入sudo apt-get install git即可.其他Linux发行版可尝试 ...

  8. Mysql-表和字段操作

    1.查看表 show tables; 2.创建表 create table test( id int primary key auto_increment, name varchar(40) not ...

  9. 《Linux/UNIX系统编程手册》读书笔记

    2018-1-30 一.UNIX.C语言以及Linux的历史回顾 1. UNIX简史.C语言的诞生 1969年,贝尔实验室的Ken Thompson首次实现了UNIX系统. 1973年,C语言步入成熟 ...

  10. Java学习个人备忘录之抽象类

    抽象类 特点:1. 方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰,抽象方法必须定义在抽象类中.该类必须也被abstract修饰2. 抽象类不可以被实例化. 为什么?  因为调 ...