BZOJ.2741.[FOTILE模拟赛]L(分块 可持久化Trie)
首先记\(sum\)为前缀异或和,那么区间\(s[l,r]=sum[l-1]^{\wedge}sum[r]\)。即一个区间异或和可以转为求两个数的异或和。
那么对\([l,r]\)的询问即求\([l-1,r]\)中某两个数异或的最大值。
区间中某一个数和已知的一个数异或的最大值可以用可持久化Trie \(O(\log v)\)求出。所以尽量确定一个数,再在区间中求最大值。
而且数据范围提醒我们可以分块。
用\(head[i]\)表示第\(i\)块的开头位置,\(Max(l,r,x)\)表示\(x\)与\([l,r]\)中某一个数异或的最大值,\(f[i][j]\)表示从第\(i\)块的开始到位置\(j\),某两个数异或的最大值是多少。
那么 \(f[i][j] = \max(f[i-1][j-1], Max(head[i], j-1, A[j]))\)。可以在\(O(n\sqrt n\log v)\)时间内预处理。(\(A[]\)是前缀异或和)
查询的时候,设\(x\)表示\(l\)后面的第一块,若\(l,r\)在同一块里,则 \(ans = Max(l, r, A[i]), i\in[l,r]\)。(对啊 和自己异或也没什么意义)
否则 \(ans = \max(f[x][r], Max(l, r, A[i]))\),\(i\in[l,begin[x]-1]\)。
对\([1,r]\)的询问,可能会有同上一题一样的边界问题(可以异或0)?把\(A[0]=0\)也试一遍就行了。。
询问复杂度同样\(O(q\sqrt n\log v)\)。
//11020kb 8232ms
#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 500000//为什么50000WA+TLE啊 QAQ
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define BIT 30
typedef long long LL;
const int N=12005,M=111;
int root[N],A[N],bel[N],H[N],f[M][N];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Trie
{
#define S N*32
int tot,son[S][2],sz[S];
void Insert(int x,int y,int v)
{
for(int i=BIT; ~i; --i)
{
int c=v>>i&1;
son[x][c]=++tot, son[x][c^1]=son[y][c^1];
x=tot, y=son[y][c];
sz[x]=sz[y]+1;
}
}
int Query(int x,int y,int v)
{
int res=0;
for(int i=BIT; ~i; --i)
{
int c=(v>>i&1)^1;
if(sz[son[y][c]]-sz[son[x][c]]>0)
x=son[x][c], y=son[y][c], res|=1<<i;
else
c^=1, x=son[x][c], y=son[y][c];
}
return res;
}
}T;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
int main()
{
int n=read(),Q=read(),size=sqrt(n);
for(int i=1; i<=n; ++i)
bel[i]=(i-1)/size+1, T.Insert(root[i]=++T.tot,root[i-1],A[i]=A[i-1]^read());//^不是+ ==
H[1]=1;
for(int i=2,lim=bel[n]; i<=lim; ++i) H[i]=H[i-1]+size;
for(int i=1,lim=bel[n]; i<=lim; ++i)
for(int j=H[i]+1,rtl=root[H[i]-1]; j<=n; ++j)
f[i][j]=std::max(f[i][j-1],T.Query(rtl,root[j-1],A[j]));
for(int l,r,x,y,ans=0; Q--; )
{
x=((LL)read()+ans)%n+1, y=((LL)read()+ans)%n+1;//read()%n+ans%n 都可能爆int。。and LL要在括号里面。。
l=std::min(x,y), r=std::max(x,y);
--l, ans=0;
if(bel[l]==bel[r])
for(int i=l,rtl=root[std::max(0,l-1)],rtr=root[r]; i<=r; ++i)
ans=std::max(ans,T.Query(rtl,rtr,A[i]));
else
{
ans=f[bel[l]+1][r];
for(int i=l,lim=H[bel[l]+1]-1,rtl=root[std::max(0,l-1)],rtr=root[r]; i<=lim; ++i)
ans=std::max(ans,T.Query(rtl,rtr,A[i]));
}
printf("%d\n",ans);
}
return 0;
}
BZOJ.2741.[FOTILE模拟赛]L(分块 可持久化Trie)的更多相关文章
- bzoj 2741 [FOTILE模拟赛] L
Description 多个询问l,r,求所有子区间异或和中最大是多少 强制在线 Solution 分块+可持久化trie 1.对于每块的左端点L,预处理出L到任意一个i,[L,j] 间所有子区间异或 ...
- 【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 [分块 可持久化Trie]
题意: 区间内最大连续异或和 5点调试到现在....人生无望 但总算A掉了 一开始想错可持久化trie的作用了...可持久化trie可以求一个数与一个数集(区间中的一个数)的最大异或和 做法比较明显, ...
- BZOJ2741 FOTILE模拟赛L(分块+可持久化trie)
显然做个前缀和之后变成询问区间内两个数异或最大值. 一种暴力做法是建好可持久化trie后直接枚举其中一个数查询,复杂度O(nmlogv). 观察到数据范围很微妙.考虑瞎分块. 设f[i][j]为第i个 ...
- 【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 .. ...
- BZOJ2741:[FOTILE模拟赛]L
Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 .. ...
- 【BZOJ】【2741】【FOTILE模拟赛】L
可持久化Trie+分块 神题……Orz zyf & lyd 首先我们先将整个序列搞个前缀异或和,那么某一段的异或和,就变成了两个数的异或和,所以我们就将询问[某个区间中最大的区间异或和]改变成 ...
随机推荐
- Linux组管理和权限管理
⒈Linux组基本介绍 1)在Linux中的每个用户必须属于一个组,不能独立于组外. 2)Linux中每个文件都有所有者.所在组.其它组的概念 ①所有者 一般(默认)为文件的创建者,谁创建了该文件,就 ...
- elasticsearch5.0集群大数据量迁移方法及注意事项
当es集群的数据量较小的情况下elasticdump这个工具比较方便,但是当数据量达到一定级别比如上百G的时候,elasticdump速度就很慢了,此时我们可以使用快照的方法进行备份 elasticd ...
- jdbc驱动加载
使用sqlserver数据库时,加载驱动: Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); Strin ...
- java ServerSocket
public Socket accept() //等待连接,该方法阻塞 public void close() //关闭服务器套接字 ServerSocket只连一次的程序 /* this is se ...
- laravel 集合
最近一直在用laravel框架,比较喜欢laravel的ORM(通常我们理解的Model)...但是默认情况下,Eloquent 查询的结果总是返回 Collection 实例...所有不得不了解co ...
- Windows安装Nginx
环境:Windows 10 Nginx :nginx-1.13.12 安装步骤: 1.下载Nginx 进入官方网站下载页面 https://nginx.org/en/download.html 可以看 ...
- 《JavaScript 高级程序设计》第二章:在HTML中使用JavaScript
script 标记是 netspace 公司最早为在 html中引入 javascript代码而创造的HTML元素,并最终被 HTML规范采纳. script 标记有四个比较重要的属性: src ty ...
- JDBC事务,银行转账,货物进出库等等。
1:转账业务 转账必须执行2个sql语句(update更新)都成功的情况下,提交事务,如果有一个失败,则2个都回滚事务2:事务应该具有4个属性:原子性.一致性.隔离性.持久性.这四个属性通常称为ACI ...
- hihocoder 1343 : Stable Members【拓扑排序】
hihocoder #1343:题目 解释:一个学习小组,一共有N个学员,一个主管.每个学员都有自己的导师(一个或者多个),导师可以是其他学员也可以是主管.每周学员都要把自己的学习报告和收到的报告提交 ...
- python全栈开发day28-网络编程之粘包、解决粘包,上传和下载的作业
一.昨日内容回顾 1. tcp和udp编码 2. 自定义mysocket解决编码问题 二.今日内容总结 1.粘包 1)产生粘包原因: (1).接收方不知道消息之间的边界,不知道一次性要取多少字节的数据 ...