[BZOJ4103][Thu Summer Camp 2015]异或运算
Posted xjr_01
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ4103][Thu Summer Camp 2015]异或运算相关的知识,希望对你有一定的参考价值。
[BZOJ4103][Thu Summer Camp 2015]异或运算
试题描述
给定长度为n的数列X={x1,x2,...,xn}和长度为m的数列Y={y1,y2,...,ym},令矩阵A中第i行第j列的值Aij=xi xor yj,每次询问给定矩形区域i∈[u,d],j∈[l,r],找出第k大的Aij。
输入
第一行包含两个正整数n,m,分别表示两个数列的长度
第二行包含n个非负整数xi
第三行包含m个非负整数yj
第四行包含一个正整数p,表示询问次数
随后p行,每行均包含5个正整数,用来描述一次询问,每行包含五个正整数u,d,l,r,k,含义如题意所述。
输出
共p行,每行包含一个非负整数,表示此次询问的答案。
输入示例
3 3 1 2 4 7 6 5 3 1 2 1 2 2 1 2 1 3 4 2 3 2 3 4
输出示例
6 5 1
数据规模及约定
对于100%的数据,0<=Xi,Yj<2^31,
1<=u<=d<=n<=1000,
1<=l<=r<=m<=300000,
1<=k<=(d-u+1)*(r-l+1),
1<=p<=500
题解
注意到 n 很小,所以我们可以一维暴力,另一维可持久化 trie。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <algorithm> using namespace std; int read() { int x = 0, f = 1; char c = getchar(); while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); } while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); } return x * f; } #define maxn 1010 #define maxm 300010 #define maxnode 9600010 #define bin 30 #define oo 2147483647 int n, m, X[maxn]; int ToT, rt[maxm], ch[maxnode][2], siz[maxnode]; void update(int& y, int x, int p, int val) { siz[y = ++ToT] = siz[x] + 1; if(p < 0) return ; memcpy(ch[y], ch[x], sizeof(ch[x])); update(ch[y][val>>p&1], ch[x][val>>p&1], p - 1, val); return ; } int lrt[maxn], rrt[maxn]; int qkth(int xl, int xr, int yl, int yr, int K) { for(int i = xl; i <= xr; i++) lrt[i] = rt[yl-1], rrt[i] = rt[yr]; int ans = 0; for(int i = bin; i >= 0; i--) { int tmp = 0; for(int j = xl; j <= xr; j++) tmp += siz[ch[rrt[j]][X[j]>>i&1^1]] - siz[ch[lrt[j]][X[j]>>i&1^1]]; if(K <= tmp) { for(int j = xl; j <= xr; j++) lrt[j] = ch[lrt[j]][X[j]>>i&1^1], rrt[j] = ch[rrt[j]][X[j]>>i&1^1]; ans = ans << 1 | 1; } else { K -= tmp; for(int j = xl; j <= xr; j++) lrt[j] = ch[lrt[j]][X[j]>>i&1], rrt[j] = ch[rrt[j]][X[j]>>i&1]; ans <<= 1; } } return ans; } int main() { n = read(); m = read(); for(int i = 1; i <= n; i++) X[i] = read(); for(int i = 1; i <= m; i++) update(rt[i], rt[i-1], bin, read()); int q = read(); while(q--) { int xl = read(), xr = read(), yl = read(), yr = read(), k = read(); printf("%d\n", qkth(xl, xr, yl, yr, k)); } return 0; }
以上是关于[BZOJ4103][Thu Summer Camp 2015]异或运算的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ4103[Thu Summer Camp 2015]异或运算 可持久化Trie树
bzoj4103[Thu Summer Camp 2015]异或运算(可持久化trie树)
bzoj4103 [Thu Summer Camp 2015]异或运算(可持久化trie)
bzoj4103[Thu Summer Camp 2015]异或运算 可持久化Trie树