BZOJ4103 [Thu Summer Camp 2015]异或运算 【可持久化trie树】
题目链接
题解
一眼看过去是二维结构,实则未然需要树套树之类的数据结构
区域异或和,就一定是可持久化\(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树】的更多相关文章
- [BZOJ4103][Thu Summer Camp 2015]异或运算 可持久化Trie树
4103: [Thu Summer Camp 2015]异或运算 Time Limit: 20 Sec Memory Limit: 512 MB Description 给定长度为n的数列X={x1 ...
- 【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 ...
- BZOJ 4103: [Thu Summer Camp 2015]异或运算 可持久化trie
开始想了一个二分+可持久化trie验证,比正解多一个 log 仔细思考,你发现你可以直接按位枚举,然后在可持久化 trie 上二分就好了. code: #include <bits/stdc++ ...
- 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 ...
- bzoj4103: [Thu Summer Camp 2015]异或运算
对于每个询问暴力枚举x~y,然后在Trie去找第k大,开始我写了个二分答案然后算比当前答案大的个数,打了个第10个点的表就跑出19s+比bzoj垫底还慢4s+ 然而不用二分,直接1000个点一起在树上 ...
- 【BZOJ 4103】 [Thu Summer Camp 2015]异或运算 可持久化01Trie
我们观察数据:树套树 PASS 主席树 PASS 一层一个Trie PASS 再看,异或!我们就把目光暂时定在01Tire然后我们发现,我们可以带着一堆点在01Trie上行走,因为O(n*q* ...
- 【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 ...
- [BZOJ 4103] [Thu Summer Camp 2015] 异或运算 【可持久化Trie】
题目链接:BZOJ - 4103 题目分析 THUSC滚粗之后一直没有写这道题,从来没写过可持久化Trie,发现其实和可持久化线段树都是一样的.嗯,有些东西就是明白得太晚. 首先Orz ZYF-ZYF ...
- [十二省联考2019]异或粽子——可持久化trie树+堆
题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...
随机推荐
- datawindow自动换行打印,需结合该函数一起使用
1.设置 具体步骤如下: 1) 在DataWindow Painter中打开此DataWindow对象. 2) 在需设定自动折行的列上双击鼠标, 弹开此列的属性窗口. 3) 选择P ...
- TPO-16 C1 Reserve the room for a rehearsal
TPO-16 C1 Reserve the room for a rehearsal 第 1 段 1.Listen to a conversation between a Student and a ...
- Java开发工程师(Web方向) - 02.Servlet技术 - 第3章.Servlet应用
第3章.Servlet应用 转发与重定向 转发:浏览器发送资源请求到ServletA后,ServletA传递请求给ServletB,ServletB生成响应后返回给浏览器. 请求转发:forward: ...
- 教你一招,提升你Python代码的可读性,小技巧
Python的初学者,开发者都应该知道的代码可读性提高技巧,本篇主要介绍了如下内容: PEP 8是什么以及它存在的原因 为什么你应该编写符合PEP 8标准的代码 如何编写符合PEP 8的代码 为什么我 ...
- fizzbuzz Python很有意思的解法
写一个程序,打印数字1到100,3的倍数打印“Fizz”来替换这个数,5的倍数打印“Buzz”,对于既是3的倍数又是5的倍数的数字打印“FizzBuzz” 题目不难,解起来容易,用for循环做if,e ...
- lintcode491 回文数
回文数 判断一个正整数是不是回文数. 回文数的定义是,将这个数反转之后,得到的数仍然是同一个数. 注意事项 给的数一定保证是32位正整数,但是反转之后的数就未必了. 您在真实的面试中是否遇到过这个题? ...
- Docker Remote API v1.24
1. Brief introduction The Remote API has replaced rcli. The daemon listens on unix:///var/run/docker ...
- vuejs学习之 项目打包之后的首屏加载优化
vuejs学习之 项目打包之后的首屏加载优化 一:使用CDN资源 我们在打包时,会将package.json里,dependencies对象里插件打包起来,我们可以将其中的一些使用cdn的方式加载,例 ...
- PHP 5.6.32 增加pdo_dblib.so拓展
首先说明,php增加pdo_dblib.so拓展不需要重新编译php源文件,只需要增加dblib源包即可. 1.下载安装所需包 1.#下载 wget http://mirrors.ibiblio.or ...
- Thunder团队第六周 - Scrum会议2
Scrum会议2 小组名称:Thunder 项目名称:i阅app Scrum Master:宋雨 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...