传送门

解题思路

  首先求出前缀异或和,那么问题就转化成了区间内选两个数使得其异或和最大。数据范围不是很大考虑分块,设\(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. day26—JavaScript对CSS样式的获取和修改实践

    转行学开发,代码100天——2018-04-11 通过JavaScript获取和修改HTML元素及CSS属性是其一个基本功能.对于CSS样式通常有行内样式,外部样式,内嵌样式之分. 如: 行内样式: ...

  2. SPSS详细教程:OR值的计算

    SPSS详细教程:OR值的计算 一.问题与数据 研究者想要探索人群中不同性别者喜欢竞技类或娱乐性体育活动是否有差异.研究者从学习运动医学的学生中随机招募50名学生,记录性别并询问他们喜欢竞技类还是娱乐 ...

  3. Jmeter接口测试报告模板优化(续)

    在之前的基础上又优化了一下: 1.增加了对接口响应时间段的统计,如小于0.5s的请求有多少,0.5-1s的有多少,大于1s的有多少.可以自行修改.且不同范围内的时间字体颜色不一样,便于区分. < ...

  4. WebApi系列~基于RESTful标准的Web Api 转载 https://www.cnblogs.com/lori/p/3555737.html

    微软的web api是在vs2012上的mvc4项目绑定发行的,它提出的web api是完全基于RESTful标准的,完全不同于之前的(同是SOAP协议的)wcf和webService,它是简单,代码 ...

  5. js面向对象程序设计之构造函数

    再上一篇的开头说了创建对象的两种方式,一种是Object构造函数的方式,一种是对象字面量的方法.但这些方式创建多个对象的时候都会产生大量的重复代码.经过技术的进步也演化出来许多的创建对象的模式.本章会 ...

  6. PHP防采集方法代码

    <?php /** * FileName:test.php * Summary: 防采集 */ $HTTP_REFERER = $_SERVER["HTTP_REFERER" ...

  7. JavaScript 表单验证正则表达式大全

    JavaScript 表单验证正则表达式大全[转载] 匹配中文字符的正则表达式: [u4e00-u9fa5] 评注:匹配中文还真是个头疼的事,有了这个表达式就好办了 匹配双字节字符(包括汉字在内):[ ...

  8. 动态规划-递推-HDU2048

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2048 全错=全不匹配 设当前全错的个数是dp[n] 那么前(n-1)个全错的话,第n个数就可以从前(n- ...

  9. debain8 安装mysql8

    一.下载apt源 https://dev.mysql.com/downloads/repo/apt/ 二.更新apt sudo apt-get update 三.安装mysql sudo apt-ge ...

  10. [POJ3612] Telephone Wire(暴力dp+剪枝)

    [POJ3612] Telephone Wire(暴力dp+剪枝) 题面 有N根电线杆,初始高度为h[i],要给相邻的两根连线.可以选择拔高其中一部分电线杆,把一根电线杆拔高\(\Delta H\)的 ...