zoukankan      html  css  js  c++  java
  • [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
    ", qkth(xl, xr, yl, yr, k));
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    弹性盒子
    bzoj4237 稻草人
    bzoj2654 tree
    bzoj4813 [Cqoi2017]小Q的棋盘
    bzoj1014 [JSOI2008]火星人
    bzoj3242 [Noi2013]快餐店
    bzoj4025 二分图
    bzoj3237 [Ahoi2013]连通图
    bzoj3244 [Noi2013]树的计数
    bzoj2431 [HAOI2009]逆序对数列
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6741722.html
Copyright © 2011-2022 走看看