传送门

解题思路

  首先求出前缀异或和,那么问题就转化成了区间内选两个数使得其异或和最大。数据范围不是很大考虑分块,设\(f[x][i]\)表示第\(x\)块开头到\(i\)这个位置与\(a[i]\)异或得到的最大的数,而对\(f\)求前缀\(max\)就可以得出每一块的开头到后面任意一点的区间内异或最大。而求\(f\)的过程实际是从区间内取一个数和给定数异或和最大,那么这个可以用\(0/1\) \(Trie\)来做,就可以造一棵可持久化\(Trie\)。询问时整块直接调用\(f\),前面的小块直接用可持久化\(Trie\)求解,时间复杂度\(O(n\sqrt(n) logn)\)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath> using namespace std;
const int N=12005;
const int M=N*60;
typedef long long LL; template<class T> void rd(T &x){
x=0; char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
}
inline int max(int x,int y) {return x>y?x:y;} int n,m,siz,num,rt[N],tot,bl[N],l[N],r[N];
int a[N],f[205][N],lstans,zz[N]; struct Trie{
int ch[M][2],sum[M];
void insert(int pre,int &x,int now,int d){
x=++tot; sum[x]=sum[pre]+1; if(!d) return ;
ch[x][0]=ch[pre][0]; ch[x][1]=ch[pre][1];
if(now&(1<<(d-1))) insert(ch[pre][1],ch[x][1],now,d-1);
else insert(ch[pre][0],ch[x][0],now,d-1);
}
int query(int u,int v,int now,int d){
if(!d) return 0;
if(now&(1<<(d-1))) {
if(sum[ch[u][0]]-sum[ch[v][0]]!=0)
return (query(ch[u][0],ch[v][0],now,d-1))|(1<<(d-1));
else return query(ch[u][1],ch[v][1],now,d-1);
}
else {
if(sum[ch[u][1]]-sum[ch[v][1]]!=0)
return (query(ch[u][1],ch[v][1],now,d-1)|(1<<(d-1)));
else return query(ch[u][0],ch[v][0],now,d-1);
}
}
}tree; inline void prework(){
for(int i=1;i<=num;++i)
for(int j=l[i]+1;j<=n;++j)
f[i][j]=tree.query(rt[j],rt[l[i]-1],a[j],31);
// for(int i=1;i<=num;i++)
// for(int j=l[i]+1;j<=n;j++)
// printf("f[%d][%d]=%lld\n",i,j,f[i][j]);
for(int i=1;i<=num;++i)
for(int j=l[i]+1;j<=n;++j)
f[i][j]=max(f[i][j],f[i][j-1]);
} inline int ask(int x,int y){
int ret=0;
if(bl[x]==bl[y]){
for(int i=x;i<y;++i)
ret=max(ret,tree.query(rt[y],rt[max(0,x-1)],a[i],31));
return ret;
}
ret=f[bl[x]+1][y];
for(int i=x;i<=r[bl[x]];++i)
ret=max(ret,tree.query(rt[y],rt[max(0,x-1)],a[i],31));
return ret;
} signed main(){
rd(n),rd(m); siz=sqrt(n);
num=n/siz; if(n%siz) num++;
for(int i=1;i<=n;++i){
rd(a[i]); bl[i]=(i-1)/siz+1; a[i]^=a[i-1];
tree.insert(rt[i-1],rt[i],a[i],31);
}
for(int i=1;i<=num;++i) l[i]=(i-1)*siz+1,r[i]=i*siz;
r[num]=n; prework(); int L,R;
while(m--){
rd(L); rd(R);
L=((LL)lstans+L)%n+1,R=((LL)lstans+R)%n+1;
if(L>R) swap(L,R); lstans=ask(L-1,R);
printf("%d\n",lstans);
}
return 0;
}

BZOJ 2741: 【FOTILE模拟赛】L(可持久化Trie+分块)的更多相关文章

  1. BZOJ.2741.[FOTILE模拟赛]L(分块 可持久化Trie)

    题目链接 首先记\(sum\)为前缀异或和,那么区间\(s[l,r]=sum[l-1]^{\wedge}sum[r]\).即一个区间异或和可以转为求两个数的异或和. 那么对\([l,r]\)的询问即求 ...

  2. bzoj 2741 [FOTILE模拟赛] L

    Description 多个询问l,r,求所有子区间异或和中最大是多少 强制在线 Solution 分块+可持久化trie 1.对于每块的左端点L,预处理出L到任意一个i,[L,j] 间所有子区间异或 ...

  3. 【bzoj2741】[FOTILE模拟赛]L 可持久化Trie树+分块

    题目描述 FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor A ...

  4. 【BZOJ2741】【块状链表+可持久化trie】FOTILE模拟赛L

    Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 .. ...

  5. BZOJ2741 FOTILE模拟赛L(分块+可持久化trie)

    显然做个前缀和之后变成询问区间内两个数异或最大值. 一种暴力做法是建好可持久化trie后直接枚举其中一个数查询,复杂度O(nmlogv). 观察到数据范围很微妙.考虑瞎分块. 设f[i][j]为第i个 ...

  6. 【bzoj2741】[FOTILE模拟赛] L

    Portal --> bzoj2741 Solution 突然沉迷分块不能自拔 考虑用分块+可持久化trie来解决这个问题 对于每一块的块头\(L\),预处理\([L,i]\)区间内的所有子区间 ...

  7. BZOJ2741:[FOTILE模拟赛]L

    Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 .. ...

  8. bzoj 2741: 【FOTILE模拟赛】L 分塊+可持久化trie

    2741: [FOTILE模拟赛]L Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1116  Solved: 292[Submit][Status] ...

  9. 【BZOJ】【2741】【FOTILE模拟赛】L

    可持久化Trie+分块 神题……Orz zyf & lyd 首先我们先将整个序列搞个前缀异或和,那么某一段的异或和,就变成了两个数的异或和,所以我们就将询问[某个区间中最大的区间异或和]改变成 ...

随机推荐

  1. 用C#调用C++DLL提示找不到DLL解决方法【转】

    用C#调用自己写的C++ DLL(x64),总是提示找不到DLL,调试可以,发布release老是提示找不到DLL(dll文件确定存在) 原因:Visual C++的DLL分发方式没选:调试默认选择: ...

  2. PHP 中 Error 和 Exception 两种异常的特性及日志记录或显示

    PHP 文档: Error Exception 参考: 深入理解PHP原理之异常机制 我们什么时候应该使用异常 异常和错误 所有示例基于 PHP7. 应用中,关于错误的最佳实践是: 必须报告错误 开发 ...

  3. workflow-core 简介

    最近想做一个OA相关的网站开发,一直都听说有workflow的东西,之前也断断续续学习过 Workflow Foundation 4.0,还是没有搞明白到底能够用它做什么 但还是觉得workflow在 ...

  4. Maven仓库存在jar包但依旧提示无法下载

    介绍最近服务器的迁移,把原来服务器的地址都更改了,所以私服的地址也改动了,原来项目下载到本地仓库的包,但是重新构建过程中竟然发现依然要提示下载,本地仓库里面明明有包,为什么还要下载? 解决去maven ...

  5. python 可变类型和不可变类型

    1. 什么是不可变类型变量对应的值中的数据是不能被修改,如果修改就会生成一个新的值从而分配新的内存空间.不可变类型: 数字(int,long,float) 布尔(bool) 字符串(string) 元 ...

  6. 设置div标签可以输入文字

    1.contenteditable 属性可以设置div标签为克输入标签,   2.input和textarea虽然是常用的输入标签,但是这两个标签不能设置最大高度和最小高度, 随意如果想随着输入的内容 ...

  7. 简单写入excel

    import pymysql,xlwt def to_excel(table_name): host, user, passwd, db = '127.0.0.1', 'root', '123', ' ...

  8. python学习第二天标准输入输出和注释用法

    任何编程语言都有输入输出和用打交道,python也不例外,输入input(),输出print() 玖乐网络(http://www.96net.com.cn/)分享自己的心得 1,input()用法实例 ...

  9. SharePoint创建web应用程序,提示密码不正确

    使用版本SharePoint2010: $username="domain\username"$newpassword="xxxxxxxx"stsadm -o ...

  10. 屏幕坐标点转UGUI坐标【包含屏幕适配】

    using UnityEngine; public class ScreenToUI : MonoBehaviour { public const float UI_Width = 1366f; pu ...