BZOJ 4103 [Thusc 2015]异或运算 (可持久化01Trie+二分)
题目大意:给你一个长方形矩阵,位置$i,j$上的数是$a_{i}\;xor\;b_{j}$,求某个子矩阵内第$K$大的值
最先想的是二分答案然后验证,然而是$O(qnlogmloga_{i})$,不出意外会被卡..看完题解才恍然大悟
$01Trie$是具有二分性质的!因为每个节点最多有2个儿子!
先对$b$序列建可持久化$01Trie$,记录一个$sum$表示当前节点的子树内有多少个数
对于每次询问,因为$n$很小,暴力枚举$a$进行统计,记录每个a当前在01Trie的位置
接下来就是在$01Trie$上二分了
按位从高到低枚举,统计一共有多少个数这一位是1,即每个a所在$01Trie$位置 和这一位异或值为1 的子树内,记为$tot$
如果$tot>k$,说明这一位不是1,每个$a$分别向异或值是0的地方走,然后$K-=tot$,去掉这一位填1的贡献
反之每个$a$往异或值为1的地方走
最后输出答案即可
#include <set>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 301000
#define N2 10201000
#define MM 100
#define ll long long
#define dd double
#define uint unsigned int
#define mod 1000000007
#define idx(X) (X-'a')
#define it multiset<node>::iterator
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
} uint bin[];
int n,m;
uint a[N1],b[N1],pa[N1];
int px[N1],py[N1]; struct Trie{
int ch[N2][],num[N2],root[N1],tot;
int sum[N2],stk[N2],tp;
void init()
{
root[]=tot=;int x=;
for(int i=;i>=;i--){
ch[x][]=++tot;
x=ch[x][],num[x]=;
}
}
void insert(int s,int rt1,int rt2,int w)
{
int x,y,p;
y=root[rt1];
x=root[rt2]=++tot;
for(int i=;i>=;i--){
p=(s&bin[i])?:;
ch[x][p]=++tot;
ch[x][p^]=ch[y][p^];
num[ch[x][p]]=num[ch[y][p]]+w;
sum[ch[x][p]]=sum[ch[y][p]];
x=ch[x][p],y=ch[y][p];
stk[++tp]=x;
}
sum[x]++,stk[tp--]=;
while(tp){
x=stk[tp--];
sum[x]=sum[ch[x][]]+sum[ch[x][]];
}
}
uint query(int L,int R,int l,int r,int K)
{
int x,y,p;uint ans=;
y=l<?:root[l],x=root[r];
int s[],tot;
for(int j=L;j<=R;j++)
px[j]=x,py[j]=y;
for(int i=;i>=;i--)
{
s[]=,s[]=,tot=;
for(int j=L;j<=R;j++){
p=(a[j]&bin[i])?:,s[p]++;
tot+=sum[ch[px[j]][p^]]-sum[ch[py[j]][p^]];
}
if(K>tot){
K-=tot;
for(int j=L;j<=R;j++){
p=(a[j]&bin[i])?:;
if(num[ch[px[j]][p]]-num[ch[py[j]][p]]>)
px[j]=ch[px[j]][p],py[j]=ch[py[j]][p];
else px[j]=py[j]=;
}
}else{
for(int j=L;j<=R;j++){
p=(a[j]&bin[i])?:;
if(num[ch[px[j]][p^]]-num[ch[py[j]][p^]]>)
px[j]=ch[px[j]][p^],py[j]=ch[py[j]][p^];
else px[j]=py[j]=;
}ans|=bin[i];
}
}return ans;
}
}T; int main()
{
//freopen("t1.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i>=;i--)
bin[i]=(<<i);
for(int i=;i<=n;i++)
a[i]=gint();
T.init();
for(int i=;i<=m;i++)
b[i]=gint(),T.insert(b[i],i-,i,);
int Q,u,d,l,r,K;
scanf("%d",&Q);
for(int q=;q<=Q;q++)
{
u=gint(),d=gint(),l=gint(),r=gint(),K=gint();
printf("%d\n",T.query(u,d,l-,r,K));
}
return ;
}
BZOJ 4103 [Thusc 2015]异或运算 (可持久化01Trie+二分)的更多相关文章
- 【BZOJ 4103】 [Thu Summer Camp 2015]异或运算 可持久化01Trie
我们观察数据:树套树 PASS 主席树 PASS 一层一个Trie PASS 再看,异或!我们就把目光暂时定在01Tire然后我们发现,我们可以带着一堆点在01Trie上行走,因为O(n*q* ...
- [BZOJ4103][Thu Summer Camp 2015]异或运算 可持久化Trie树
4103: [Thu Summer Camp 2015]异或运算 Time Limit: 20 Sec Memory Limit: 512 MB Description 给定长度为n的数列X={x1 ...
- BZOJ 4103: [Thu Summer Camp 2015]异或运算 可持久化trie
开始想了一个二分+可持久化trie验证,比正解多一个 log 仔细思考,你发现你可以直接按位枚举,然后在可持久化 trie 上二分就好了. code: #include <bits/stdc++ ...
- 【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】 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 ...
- BZOJ 3689 异或之 (可持久化01Trie+堆)
题目大意:给你一个序列,求出第$K$大的两两异或值 先建出来可持久化$01Trie$ 用一个$set$/堆存结构体,存某个异或对$<i,j>$的第二关键字$j$,以及$ai\;xor\;a ...
- BZOJ 3261 最大异或和 (可持久化01Trie)
题目大意:让你维护一个序列,支持在序列末插入一个数,支持询问$[l,r]$区间内选择一个位置$p$,使$xor\sum_{i=p}^{n}a_{i}$最大 可持久化$01Trie$裸题,把 区间异或和 ...
- P5283 [十二省联考2019]异或粽子 可持久化01Trie+线段树
$ \color{#0066ff}{ 题目描述 }$ 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 \(n\) 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 ...
随机推荐
- Mac 如何寻找Mac自带的IDLE
Mac 如何寻找Mac自带的IDLE 每次要打开IDLE时,需要如下动作:打开terminal --> 输入idle --> 回车,就自动打开IDLE了 图标如下: 选择在“Finder中 ...
- LeetCode Golang 4. 寻找两个有序数组的中位数
4. 寻找两个有序数组的中位数 很明显我偷了懒, 没有给出正确的算法,因为官方的解法需要时间仔细看一下... func findMedianSortedArrays(nums1 []int, nums ...
- JS怎样写闰年
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- arttemplate模板引擎里面多层循环
要使用支持原生js的插件: 代码截图: json数据 { "list": [ { "name": "学历层次", "item&qu ...
- Pyhton学习——Day11
# Python中的内部模块# 函数学习的意义:抽取重复代码# 模块:不用重复写,模块及py文件,提高了代码的可维护性,其次,编写代码不必从零开始,当一个模块编写完毕,不必再重复编写# import ...
- js 时间戳 中国标准时间 年月日 日期之间的转换
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- git与github的连接流程
https://blog.csdn.net/sssssuuuuu666/article/details/78565381 https://www.cnblogs.com/wzd5230/p/49064 ...
- Java 中关于default 访问权限的讨论
Java中关于成员变量访问权限问题一般书中会给出如下表格: 简单地描述一下表中的内容:用private 修饰的成员变量只能在类内部访问:用default修饰的成员变量可以再内部访问,也可以被同个包(同 ...
- C#-入门思维导图
C#-入门思维导图 百度云盘 链接:http://pan.baidu.com/s/1jI5zMS2 密码:0ypc 如有错误,请告知我
- dubbo标签
<dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心. <dubbo:reference/&g ...