题意:给定\(a[l...r]\),多次询问区间\([l,r]\)中的最大连续异或和\(a_i⊕a_{i+1}⊕...⊕a_{j},l≤i≤j≤r\)

一眼过去认为是不可做的,但题目给出\(n=1.2e4\),提供了分块暴力的余地

首先处理成前缀形式,对于询问\([l,r]\)既为\([l-1,r]\)中寻找两个数xor最大

维护\(f[i][j]\):第i个块到第j个数的任意异或最大值

这个只需\(O(30*n\sqrt{n})\)的代价即可预处理

对于每次询问,首个残缺的块暴力,其余块直接由\(f\)得到答案,复杂度\(O(30*m\sqrt{n})\)

Yet Another Similar Problem : https://www.cnblogs.com/caturra/p/8429665.html

#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define iter(i,j) for(int i=0;i<(j).size();i++)
#define print(a) printf("%lld",(ll)a)
#define println(a) printf("%lld\n",(ll)a)
#define printbk(a) printf("%lld ",(ll)a)
#define IOS ios::sync_with_stdio(0)
using namespace std;
const int MAXN = 2e4+11;
const int oo = 0x3f3f3f3f;
typedef long long ll;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int T[MAXN],a[MAXN],b[MAXN];
struct TRIE{
int tot;
int son[MAXN*40][2],size[MAXN*40];
void init(){
tot=0;
son[0][0]=son[0][1]=size[0]=0;
memset(T,0,sizeof T);
}
int insert(int old,int val){
int rt,o;rt=o=++tot;
rrep(i,30,0){
son[o][0]=son[old][0],
son[o][1]=son[old][1];
size[o]=size[old]+1;
int wh=val>>i&1;
son[o][wh]=++tot;
old=son[old][wh];
o=son[o][wh];
}
size[o]=size[old]+1;
return rt;
}
int query(int l,int r,int val){
int ans=0;
rrep(i,30,0){
int wh=val>>i&1;
if(size[son[r][wh^1]]-size[son[l][wh^1]]){
ans|=(1<<i),r=son[r][wh^1],l=son[l][wh^1];
}else{
r=son[r][wh],
l=son[l][wh];
}
}
return ans;
}
}trie;
vector<int> vec[233];
int head[233],pos[MAXN];
int f[233][MAXN];
int main(){
int n,m;
while(cin>>n>>m){
trie.init();
rep(i,1,n) a[i]=read();
rep(i,1,n) b[i]=b[i-1]^a[i];
rep(i,1,n) T[i]=trie.insert(T[i-1],b[i]);
int sz=sqrt(n)+1;
rep(i,1,sz+3) vec[i].clear();
int now=0;
rep(i,1,n){
if(vec[now].size()==sz||now==0) head[++now]=i;
vec[now].push_back(a[i]);
pos[i]=now;
}
memset(f,0,sizeof f);
rep(i,1,now){
rep(j,head[i],n){
f[i][j]=max(f[i][j-1],trie.query(T[head[i]-1],T[j],b[j]));
}
}
int ans=0;
while(m--){
int l=read();
int r=read();
int x=((ll)l+ans)%n+1;
int y=((ll)r+ans)%n+1;
l=min(x,y); r=max(x,y);
ans=0;
--l;
if(pos[l]==pos[r]){
rep(i,l,r){
ans=max(ans,trie.query(T[l-1],T[r],b[i]));
}
}else{
ans=f[pos[l]+1][r];//best[pos[l+1]][r]
rep(i,l,head[pos[l]+1]-1){
ans=max(ans,trie.query(T[l-1],T[r],b[i]));
}
}
println(ans);
}
}
return 0;
}

BZOJ - 2741 分块维护最大连续异或和的更多相关文章

  1. bzoj 2741 分块+可持久化trie

    多个询问l,r,求所有子区间异或和中最大是多少 强制在线 做法: 分块+可持久化trie 1.对于每块的左端点i,预处理出i到任意一个j,()i,j)间所有子区间异或和中最大为多少,复杂度O(\(n\ ...

  2. BZOJ 2741: 【FOTILE模拟赛】L [分块 可持久化Trie]

    题意: 区间内最大连续异或和 5点调试到现在....人生无望 但总算A掉了 一开始想错可持久化trie的作用了...可持久化trie可以求一个数与一个数集(区间中的一个数)的最大异或和 做法比较明显, ...

  3. BZOJ 2741 L (可持久化01Trie+分块)

    题目大意:给你一个序列,共有$q$个询问,每次询问区间$[L,R]$内最大连续字段异或和,强制在线,$n<=12000,m<=5000$ 有个细节没处理好$WA$了好久..还有一次$ans ...

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

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

  5. BZOJ 2741: 【FOTILE模拟赛】L(可持久化Trie+分块)

    传送门 解题思路 首先求出前缀异或和,那么问题就转化成了区间内选两个数使得其异或和最大.数据范围不是很大考虑分块,设\(f[x][i]\)表示第\(x\)块开头到\(i\)这个位置与\(a[i]\)异 ...

  6. 【BZOJ】2453: 维护队列【BZOJ】2120: 数颜色 二分+分块(暴力能A)

    先说正解:把所有相同的数相成一个链在每一个区间里的种数就是不同链的链头,那么记录每个数的上个相同数所在位置,那么只要找出l到r之间前驱值在l之前的数的个数就可以了 本人打的暴力,有一个小技巧,用cha ...

  7. BZOJ 2741 【FOTILE模拟赛】L(可持久化trie)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2741 思路:我们先将a变成a的异或前缀,这样问题就变成了,在l-1到r区间内,找出i,j令a[i]^ ...

  8. bzoj 2741: 【FOTILE模拟赛】L

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

  9. BZOJ 5495: [2019省队联测]异或粽子 (trie树)

    这题果然是原题[BZOJ 3689 异或之].看了BZOJ原题题解,发现自己sb了,直接每个位置维护一个值保存找到了以这个位置为右端点的第几大,初始全部都是1,把每个位置作为右端点能够异或出来的最大值 ...

随机推荐

  1. [JAVA] 冻结Excel的第一行或第一列

    可以按照如下设置创建冻结窗口. sheet.createFreezePane( 3, 2, 3, 2 ); 前两个参数是你要用来拆分的列数和行数.后两个参数是下面窗口的可见象限,其中第三个参数是右边区 ...

  2. TensorFlow全新的数据读取方式:Dataset API入门教程

    TensorFlow.data : http://tech.ifeng.com/a/20171109/44752505_0.shtml Pytorch:https://ptorch.com/docs/ ...

  3. C#序列化效率对比

    原文出处:https://www.cnblogs.com/landeanfen/p/4627383.html 从使用序列化到现在,用到的无非下面几种方式:(1)JavaScriptSerializer ...

  4. linux的操作

    对tomcat的操作 打开终端 cd /java/tomcat#执行bin/startup.sh #启动tomcatbin/shutdown.sh #停止tomcat tail -f logs/cat ...

  5. django model ValueQuerySet QuerySet 转换成JSON

    这里我有4个字段需要使用外键,那么在调取数据的时候就可以使用两个'_'进行调取,当然条件必须需要从前端传进来 models.py class HostInfo(models.Model): host_ ...

  6. iframe是怎么跳转的

    在main.jsp中 <iframe frameborder="0" marginheight="0" marginwidth="0" ...

  7. Ubuntu 将应用程序 固定到快快速启动栏(以Sublime为例)

    因为Sublime Text并不是需要安装,所以缺少Ubuntu桌面运行的一些基本配置,比如不能将它加入桌面侧边的启动器. 而Ubuntu上也没有快捷方式的说法,而通过软件中心安装的软件就有图标,并能 ...

  8. 使用 console.time() 计算js代码执行时间

    console.time('hellor'); for(var i=0;i<100000;i++){} console.timeEnd('hellor');

  9. 洛谷P4234 最小差值生成树(lct动态维护最小生成树)

    题目描述 给定一个标号为从 11 到 nn 的.有 mm 条边的无向图,求边权最大值与最小值的差值最小的生成树. 输入输出格式 输入格式:   第一行两个数 n, mn,m ,表示图的点和边的数量. ...

  10. Oracle定時email通知

    small_program_task 這張表的資料是待發送的email通知,再次之前已經有一個job會定時掃描固定時間內未接收到小程式回報狀態將其寫入到該表,send_flag為N,表示為寄過通知.e ...