BZOJ2741 FOTILE模拟赛L(分块+可持久化trie)
显然做个前缀和之后变成询问区间内两个数异或最大值。
一种暴力做法是建好可持久化trie后直接枚举其中一个数查询,复杂度O(nmlogv)。
观察到数据范围很微妙。考虑瞎分块。
设f[i][j]为第i个块中的数和第j个数的异或最大值。显然建一棵可持久化trie就可以以O(n√nlogv)的复杂度搞出来。
有了这个后考虑怎么查询。对于完整的块内的数,给f再搞一个st表就可以了。而其他部分暴力枚举每个数,在可持久化trie上查询即可。
常数巨大。块大小改成√nlogn后在darkbzoj上差10ms就T了,bzoj上自然过不了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 12010
#define BLOCK 120
#define u(x,p) x>>p&1^1
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,a[N],f[BLOCK][N][],root[N],L[BLOCK],R[BLOCK],pos[N],lg2[N],cnt=,lastans,block;
struct data{int ch[],s;
}tree[N<<];
void ins(int &k,int x,int p)
{
tree[++cnt]=tree[k];k=cnt;tree[k].s++;
if (p<) return;
ins(tree[k].ch[x>>p&],x,p-);
}
int query(int l,int r,int x,int p)
{
if (p<) return ;
if (tree[tree[r].ch[u(x,p)]].s>tree[tree[l].ch[u(x,p)]].s)
return query(tree[l].ch[u(x,p)],tree[r].ch[u(x,p)],x,p-)+(<<p);
else query(tree[l].ch[x>>p&],tree[r].ch[x>>p&],x,p-);
}
void build()
{
for (int i=;i<=n;i++)
{
root[i]=root[i-];
ins(root[i],a[i],);
}
}
int query(int i,int x,int y)
{
return max(f[i][x][lg2[y-x+]],f[i][y-(<<lg2[y-x+])+][lg2[y-x+]]);
}
void divide()
{
lg2[]=;
for (int i=;i<=n;i++)
{
lg2[i]=lg2[i-];
if ((<<lg2[i])<=i) lg2[i]++;
}
block=sqrt(n*lg2[n]);block=min(max(block,),n);
for (int i=;i<=n/block;i++) L[i]=(i-)*block+,R[i]=i*block;
if (n%block) L[n/block+]=(n/block)*block+,R[n/block+]=n,block=n/block+;
else block=n/block;
for (int i=;i<=block;i++)
for (int j=L[i];j<=R[i];j++)
pos[j]=i;
for (int i=;i<=n;i++)
for (int j=;j<=block;j++)
f[j][i][]=query(root[L[j]-],root[R[j]],a[i],);
for (int i=;i<=block;i++)
for (int j=;j<;j++)
for (int k=;k<=n;k++)
f[i][k][j]=max(f[i][k][j-],f[i][min(n,k+(<<j-))][j-]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj2741.in","r",stdin);
freopen("bzoj2741.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read()+,m=read();
for (int i=;i<=n;i++) a[i]=a[i-]^read();
build();
divide();
for (int i=;i<=m;i++)
{
int x=((unsigned int)read()+lastans)%(n-)+,y=((unsigned int)read()+lastans)%(n-)+;
if (x>y) swap(x,y);y++;
lastans=;
for (int j=pos[x]+;j<pos[y];j++)
lastans=max(lastans,query(j,x,y));
if (pos[x]==pos[y])
{
for (int j=x;j<=y;j++)
lastans=max(lastans,query(root[x-],root[y],a[j],));
}
else
{
for (int j=x;j<L[pos[x]+];j++)
lastans=max(lastans,query(root[x-],root[y],a[j],));
for (int j=y;j>R[pos[y]-];j--)
lastans=max(lastans,query(root[x-],root[y],a[j],));
}
printf("%d\n",lastans);
}
return ;
}
BZOJ2741 FOTILE模拟赛L(分块+可持久化trie)的更多相关文章
- BZOJ.2741.[FOTILE模拟赛]L(分块 可持久化Trie)
题目链接 首先记\(sum\)为前缀异或和,那么区间\(s[l,r]=sum[l-1]^{\wedge}sum[r]\).即一个区间异或和可以转为求两个数的异或和. 那么对\([l,r]\)的询问即求 ...
- BZOJ2741:[FOTILE模拟赛]L
Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 .. ...
- 【BZOJ2741】【FOTILE模拟赛】L 分块+可持久化Trie树
[BZOJ2741][FOTILE模拟赛]L Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max( ...
- 【bzoj2741】[FOTILE模拟赛] L
Portal --> bzoj2741 Solution 突然沉迷分块不能自拔 考虑用分块+可持久化trie来解决这个问题 对于每一块的块头\(L\),预处理\([L,i]\)区间内的所有子区间 ...
- bzoj 2741 [FOTILE模拟赛] L
Description 多个询问l,r,求所有子区间异或和中最大是多少 强制在线 Solution 分块+可持久化trie 1.对于每块的左端点L,预处理出L到任意一个i,[L,j] 间所有子区间异或 ...
- 【bzoj2741】[FOTILE模拟赛]L 可持久化Trie树+分块
题目描述 FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor A ...
- 【BZOJ2741】【块状链表+可持久化trie】FOTILE模拟赛L
Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 .. ...
- BZOJ 2741: 【FOTILE模拟赛】L [分块 可持久化Trie]
题意: 区间内最大连续异或和 5点调试到现在....人生无望 但总算A掉了 一开始想错可持久化trie的作用了...可持久化trie可以求一个数与一个数集(区间中的一个数)的最大异或和 做法比较明显, ...
- BZOJ2741: 【FOTILE模拟赛】L
2741: [FOTILE模拟赛]L Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 1170 Solved: 303[Submit][Status] ...
随机推荐
- kubernetes 限制网络带宽 annotation -- 注解 -- 类似 label
1.可以通过给Pod增加 kubernetes.io/ingressbandwidth和 kubernetes.io/egress-bandwidth 这两个annotation来限制Pod的网络带宽 ...
- odoo之recoed.append()方法
# 这里只是带数据到订单里面去,所以append要加append((0,0,)数据已经存在,放入到表中if dict: for line in dict: record.append((0,0,{'s ...
- vi 替换
在vi编辑器中,能够利用 :s命令能够实现字符串的替换.详细的使用方法例如以下: 1.:s/str1/str2/ 用字符串 str2 替换行中首次出现的字符串str1: 2.:s/str1/str2/ ...
- Cloud Foundry 组件
原文:https://blog.csdn.net/little_crab_0924/article/details/78022391 Cloud Foundry 组件概述 Cloud Foundry ...
- Hadoop日记Day15---MapReduce新旧api的比较
我使用hadoop的是hadoop1.1.2,而很多公司也在使用hadoop0.2x版本,因此市面上的hadoop资料版本不一,为了扩充自己的知识面,MapReduce的新旧api进行了比较研究. h ...
- Hadoop日记Day4---去除HADOOP_HOME is deprecated
去除hadoop运行时的警告 1. 档hadoop运行时,我们会看到如下图1.1所示的警告. 图 1.1 2. 虽然不影响程序运行,但是看到这样的警告信息总是觉得自己做得不够好.一步步分析,先看一下启 ...
- laraver框架学习------工厂模型填充测试数据
在laravel中填充数据有几种方式.一种是Seeder,另一种是工厂模式进行的填充. 工厂模式可以实现大批量的填充数据,数据的量可以自定义.这也为后续的软件测试提供方便. 在laravel框架有da ...
- Mysql_临时表
CREATE TEMPORARY TABLE test_info ( test_name ) NOT NULL, test_totail ,) NOT NULL DEFAULT 0.00, test_ ...
- redis在php中常用的语法(转)
String 类型操作 string是redis最基本的类型,而且string类型是二进制安全的.意思是redis的string可以包含任何数据.比如jpg图片或者序列化的对象 $redis-> ...
- PHP Lavavel 使用控制器 传递变量 以及调用 视图模板
控制器第一次入门使用 位置: 在app/Http/Controllers 目录下创建文件名格式:例如 UserController路由调用格式:Route::get('user/tom','UserC ...