题目链接

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. memory引擎和innodb引擎速度对比

    ysql> insert into innodb_test (name) select name from innodb_test; Query OK, rows affected ( min ...

  2. Ubuntu 14.04 登录 界面添加 root账号

    1打开终端输入:sudo gedit /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf 2在弹出的编辑框里加入:greeter-show-manual- ...

  3. NGUI组件整理总结

    一图流: 注意: private void RClickUI(Vector3 newPos) { this.gameObject.SetActive(true); this.transform.loc ...

  4. Python3 Tkinter-Checkbutton

    1.多选按钮创建 from tkinter import * root=Tk() Checkbutton(root,text='python').pack() root.mainloop() 2.绑定 ...

  5. ThinkPHP - 1 - 本地部署

    ThinkPHP ThinkPHP是一个快速.简单的基于MVC和面向对象的轻量级PHP开发框架,遵循Apache2开源协议发布,从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时 ...

  6. javascript打开新窗口

    一.window.open()支持环境: JavaScript1.0+/JScript1.0+/Nav2+/IE3+/Opera3+ 二.基本语法: window.open(pageURL,name, ...

  7. NSValue的valueWithBytes:objCType:方法

    + (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type; NSValue的valueWithBytes: ...

  8. 第八章 IO库

    8.1&&8.2 #include <iostream> #include <vector> #include <string> using nam ...

  9. No Route to Host from master/192.168.2.131 to master:9000 failed on socket t

    host里边添加的ip地址与当前的ip地址(ifconfig可以查看)不一致,修改当前ip地址就可以了.

  10. java — 值传递和引用传递

    在 Java 应用程序中永远不会传递对象,而只传递对象引用.因此是按引用传递对象.Java 应用程序按引用传递对象这一事实并不意味着 Java 应用程序按引用传递参数.参数可以是对象引用,而 Java ...