bzoj2741(分块+可持久化Trie)
题意中文我就不说了
解析: 分块+可持久化Trie,先得到前缀异或值,插入到Trie中,然后分块,对每一块,处理出dp[i][j](i代表第几块,j代表第几个位置),dp[i][j]代表以第i块开始的到j这个位置
的连续字串最大异或值。查询时,如果l,r不在同一块内,可以先查询l所在的块的后一个块到r的连续字串最大异或值,之前的dp就可以派上用场了,然后就是处理l到l所在块
的这段区间,取两者最大值即可。
代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=;
const int maxbit=;
int N,M,A[maxn];
int tr[maxn];
struct PerTrie
{
int next[][],num[];
int id;
void init(){ id=next[][]=next[][]=num[]=; }
int f(int x,int i){ return (x>>i)&; }
void Insert(int& rt,int pre,int x,int pos) //插入
{
rt=++id;
next[rt][]=next[pre][];
next[rt][]=next[pre][];
num[rt]=num[pre]+;
if(pos==-) return;
int d=f(x,pos);
Insert(next[rt][d],next[pre][d],x,pos-);
}
int MaxXor(int l,int r,int x) //查询最大异或值,因为A[i]保存
{ //的是前缀异或值,所以得到的结果就是某一段区间的异或值
int ret=;
for(int i=maxbit;i>=;i--)
{
int d=f(x,i);
int a=next[l][d^],b=next[r][d^];
if(num[b]-num[a]>) ret|=(<<i),l=a,r=b;
else l=next[l][d],r=next[r][d];
}
return ret;
}
}PT;
int block,num,bel[maxn],dp[][maxn]; //dp保存第几块到第几个数的区间最大异或值
void init()
{
tr[]=;
PT.init();
for(int i=;i<=N;i++) PT.Insert(tr[i],tr[i-],A[i],maxbit); //插入
block=(int)sqrt(N+0.5);
num=N/block;
if(N%block) num++; //加1
memset(dp,,sizeof(dp));
bel[]=;
for(int i=;i<=N;i++) bel[i]=(i-)/block+; //记录下属于哪个块
for(int i=;i<=num;i++)
{
int st=(i-)*block+;
for(int j=st;j<=N;j++)
{
dp[i][j]=max(dp[i][j-],A[j]^A[st-]); //可能是[st,j]这段区间
dp[i][j]=max(dp[i][j],PT.MaxXor(tr[st-],tr[j],A[j])); //再找最大的
}
}
}
int GetAns(int l,int r)
{
l--;
int s=bel[l],ret=;
if(bel[r]>s) ret=dp[s+][r]; //查询从后面一个块开始的
for(int i=l;i<=min(r,s*block);i++)
{
ret=max(ret,PT.MaxXor(tr[l-],tr[r],A[i]));
}
return ret;
}
int main()
{
scanf("%d%d",&N,&M);
A[]=;
int x;
for(int i=;i<=N;i++)
{
scanf("%d",&x);
A[i]=A[i-]^x;
}
init();
int last=,l,r;
while(M--)
{
scanf("%d%d",&l,&r);
l=(l+(LL)last)%N+;
r=(r+(LL)last)%N+;
if(l>r) swap(l,r);
//printf("%d %d\n",l,r);
last=GetAns(l,r);
printf("%d\n",last);
}
return ;
}
bzoj2741(分块+可持久化Trie)的更多相关文章
- bzoj 2741 分块+可持久化trie
多个询问l,r,求所有子区间异或和中最大是多少 强制在线 做法: 分块+可持久化trie 1.对于每块的左端点i,预处理出i到任意一个j,()i,j)间所有子区间异或和中最大为多少,复杂度O(\(n\ ...
- BZOJ2741 FOTILE模拟赛L(分块+可持久化trie)
显然做个前缀和之后变成询问区间内两个数异或最大值. 一种暴力做法是建好可持久化trie后直接枚举其中一个数查询,复杂度O(nmlogv). 观察到数据范围很微妙.考虑瞎分块. 设f[i][j]为第i个 ...
- 【BZOJ2741】【FOTILE模拟赛】L 分块+可持久化Trie树
[BZOJ2741][FOTILE模拟赛]L Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max( ...
- BZOJ 2741: 【FOTILE模拟赛】L [分块 可持久化Trie]
题意: 区间内最大连续异或和 5点调试到现在....人生无望 但总算A掉了 一开始想错可持久化trie的作用了...可持久化trie可以求一个数与一个数集(区间中的一个数)的最大异或和 做法比较明显, ...
- BZOJ.2741.[FOTILE模拟赛]L(分块 可持久化Trie)
题目链接 首先记\(sum\)为前缀异或和,那么区间\(s[l,r]=sum[l-1]^{\wedge}sum[r]\).即一个区间异或和可以转为求两个数的异或和. 那么对\([l,r]\)的询问即求 ...
- 【bzoj2741】[FOTILE模拟赛]L 可持久化Trie树+分块
题目描述 FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor A ...
- BZOJ2741 【FOTILE模拟赛】L 【可持久化trie + 分块】
题目 FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj) ...
- BZOJ 2741: 【FOTILE模拟赛】L(可持久化Trie+分块)
传送门 解题思路 首先求出前缀异或和,那么问题就转化成了区间内选两个数使得其异或和最大.数据范围不是很大考虑分块,设\(f[x][i]\)表示第\(x\)块开头到\(i\)这个位置与\(a[i]\)异 ...
- 【BZOJ2741】【块状链表+可持久化trie】FOTILE模拟赛L
Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 .. ...
随机推荐
- URAL 2038 Minimum Vertex Cover
2038. Minimum Vertex Cover Time limit: 1.0 secondMemory limit: 64 MB A vertex cover of a graph is a ...
- 【每天一个Linux命令】19. 创建文件夹目录命令mkdir
命令用途 mkdir 命令用来创建指定的名称的目录 使用说明 1. 创建目录的用户在当前目录中具有写权限 2. 指定的目录名不能是当前目录中已有的目录. 命令实例 0. 帮助文件 bixiaopen ...
- SelectSort 选择排序
//SelectSort (( O(n²))) public class TestSelectSort { public int[] selectSortArray(int[] arr){ int m ...
- JVM运行时内存结构
原文转载自:http://my.oschina.net/sunchp/blog/369707 1.JVM内存模型 JVM运行时内存=共享内存区+线程内存区 1).共享内存区 共享内存区=持久带+堆 持 ...
- 弹出框layer的使用封装
layer弹出框官方网址:http://layer.layui.com/ layer常用方法的封装:layerTool.jsp layer.config({ extend: 'extend/layer ...
- JavaScript 数组中查找符合条件的值
数组实例的find方法,用于找出第一个符合条件的数组成员.它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员.如果没有符合条件的成员,则返回u ...
- PHP设计模式笔记四:适配器模式 -- Rango韩老师 http://www.imooc.com/learn/236
适配器模式 1.适配器模式,可以将截然不同的函数接口封装成统一的API 2.实际应用举例,PHP的数据库操作有mysql.mysqli.pdo三种,可以用适配器模式统一成一致,类似的场景还有cache ...
- 搭建完全分布式的hadoop[转]
hadoop 创建用户及hdfs权限,hdfs操作等常用shell命令 sudo addgroup hadoop#添加一个hadoop组sudo usermod -a -G hadoop larry# ...
- Eclipse 将projectBuild Path中引用的jar包自己主动复制到WEB-INF下的lib目录下
在用用 Eclipse进行Java Web开发时,web应用中引用的jar须要复制到WEB-INF下的lib目录下,否则常常出现ClassNotFound异常. 通过以下方法,能够不用手动拷贝jar包 ...
- compass模块
Compass核心模块Reset :重置CSS模块 @import "compass/reset" Layout :页面布局的控制能力 @import "compass/ ...