2018.09.30 bzoj2741: 【FOTILE模拟赛】L(分块+可持久化01trie)
传送门
数据结构经典题。
首先考虑另外一种询问方式。
已知权值val,在区间[1,n][1,n][1,n]中找一个数使得valvalval^a[i]a[i]a[i]最大。
这个可以直接01trie。
那么变成区间[l,r][l,r][l,r]之后显然可以用可持久化01trie。
但是现在不知道权值val。
所以我们用分块预处理把时间复杂度变成O(n∗sqrt(n)∗logn)O(n*sqrt(n)*logn)O(n∗sqrt(n)∗logn)的。
具体来说就是mx[i][j]mx[i][j]mx[i][j]表示从第i块开头开始到j这段区间最大的两个数的异或和。
代码:
#include<bits/stdc++.h>
#define ll long long
#define N 12005
#define P 60
using namespace std;
inline ll read(){
ll ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int n,m,sig,rt[N],blo[N];
ll lastans=0,mx[150][N],sum[N];
struct Trie{
int son[N*400][2],siz[N*400],tot;
inline int insert(ll val,int las){
int p,ret;
p=ret=++tot;
for(int i=P;~i;--i){
son[p][0]=son[las][0],son[p][1]=son[las][1],siz[p]=siz[las]+1;
ll tmp=(val>>i)&1ll;
son[p][tmp]=++tot,p=son[p][tmp],las=son[las][tmp];
}
siz[p]=siz[las]+1;
return ret;
}
inline ll query(int l,int r,ll val){
ll ret=0;
for(int i=P;~i;--i){
ll tmp=(val>>i)&1ll;
if(siz[son[r][tmp^1ll]]-siz[son[l][tmp^1ll]])ret|=1ll<<i,l=son[l][tmp^1ll],r=son[r][tmp^1ll];
else l=son[l][tmp],r=son[r][tmp];
}
return ret;
}
}T;
int main(){
n=read(),m=read(),sig=sqrt(n),T.tot=0;
for(int i=1;i<=n;++i)blo[i]=(i-1)/sig+1,rt[i]=T.insert((sum[i]=sum[i-1]^read()),rt[i-1]);
for(int i=1;i<=blo[n];++i){
ll tmp=0;
for(int j=(i-1)*sig+1;j<=n;++j)tmp=max(tmp,T.query(rt[(i-1)*sig-1],rt[j],sum[j])),mx[i][j]=tmp;
}
while(m--){
int l=(read()+lastans)%n+1,r=(read()+lastans)%n+1;
if(l>r)swap(l,r);
lastans=(blo[l]^blo[r])?mx[blo[l]+1][r]:0;
int ql=l-1,qr=min(r,blo[l]*sig);
for(int i=ql;i<=qr;++i)lastans=max(lastans,T.query(rt[l-2],rt[r],sum[i]));
printf("%lld\n",lastans);
}
return 0;
}
2018.09.30 bzoj2741: 【FOTILE模拟赛】L(分块+可持久化01trie)的更多相关文章
- BZOJ.2741.[FOTILE模拟赛]L(分块 可持久化Trie)
题目链接 首先记\(sum\)为前缀异或和,那么区间\(s[l,r]=sum[l-1]^{\wedge}sum[r]\).即一个区间异或和可以转为求两个数的异或和. 那么对\([l,r]\)的询问即求 ...
- BZOJ2741 FOTILE模拟赛L(分块+可持久化trie)
显然做个前缀和之后变成询问区间内两个数异或最大值. 一种暴力做法是建好可持久化trie后直接枚举其中一个数查询,复杂度O(nmlogv). 观察到数据范围很微妙.考虑瞎分块. 设f[i][j]为第i个 ...
- BZOJ2741:[FOTILE模拟赛]L
Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 .. ...
- 【bzoj2741】[FOTILE模拟赛] L
Portal --> bzoj2741 Solution 突然沉迷分块不能自拔 考虑用分块+可持久化trie来解决这个问题 对于每一块的块头\(L\),预处理\([L,i]\)区间内的所有子区间 ...
- bzoj 2741 [FOTILE模拟赛] L
Description 多个询问l,r,求所有子区间异或和中最大是多少 强制在线 Solution 分块+可持久化trie 1.对于每块的左端点L,预处理出L到任意一个i,[L,j] 间所有子区间异或 ...
- 【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 .. ...
- 2018.09.30 bzoj2821: 作诗(Poetize)(分块)
传送门 分块经典题目. 先将数列分块. 然后预处理出每两个块之间有多少个数出现了正偶数次. 这样查询的时候对于中间的完整块直接用预处理出的数组搞定. 剩下的暴力枚举求解. 代码: #include&l ...
- 【BZOJ2741】【FOTILE模拟赛】L 分块+可持久化Trie树
[BZOJ2741][FOTILE模拟赛]L Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max( ...
随机推荐
- bootStrap 教程 文档
参考1: https://www.w3schools.com/bootstrap/default.asp 参考1:http://www.runoob.com/bootstrap/bootstrap-i ...
- HtmlRowCreated关于e.Row.Cells[0]的获取和设置
获取采用: cmd2.Parameters.AddWithValue("@xh", e.GetValue("学号").ToString().Trim()); ...
- GPO配置时的注意事项
当两个组策略冲突时: 1.如在同一层OU,后生效的组策略有效,优先级高.在组织单元的'链接的组策略对象'中标明了组策略的先后应用次序,其中下面的组策略先应用,上面的组策略后应用,即上面的组策略优先级高 ...
- java自定义线程池
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间.那么有没有一种办法使得线程可以复用,就是执行完一个任 ...
- as3 TweenMax TweenLite方法
as3 TweenMax TweenLite方法补充(暂停.重新播放.倒序播放).现在来好好的学习一下: TweenLite.to(mc, 1.5, {x:100}); 里面的mc指所作用的对象, ...
- input 提交属性 hidden属性
name名字最好和你后台属性的成员变量对应,否则在参数传递的时候接收不到出现空指针异常.一般表单提交后input会以name的值=value的值的形式传给后台.如:<input type=&qu ...
- delphi常用函数和方法
uses ShellApi, ActiveX, ComObj, ShlObj; function HasText(Text: string; const Values: array of strin ...
- .Spark Streaming(上)--实时流计算Spark Streaming原理介
Spark入门实战系列--7.Spark Streaming(上)--实时流计算Spark Streaming原理介绍 http://www.cnblogs.com/shishanyuan/p/474 ...
- 用Python写单向链表和双向链表
链表是一种数据结构,链表在循环遍历的时候效率不高,但是在插入和删除时优势比较大. 链表由一个个节点组成. 单向链表的节点分为两个部分:存储的对象和对下一个节点的引用.注意是指向下一个节点. 而双向链表 ...
- vprintf 和 vsnpintf 的用法
函数定义: int vprintf ( const char * format, va_list arg ); printf() and friends are for normal use. vpr ...