首先我们设si为前i个数的xor和,那么对于询问区间[i,j]的xor和,就相当于si-1^sj,那么对于这道题的询问我们可以处理处si,然后对于询问[l,r],可以表示为在区间[l-1,r]里找两个数使得这两个数的xor值最大,对于区间中找一个数使得xor一个已知数的值最大我们可以用可持久化trie来完成(有疑问请移步http://www.cnblogs.com/BLADEVIL/p/3669219.html),设询问query(l,r,x)表示x与区间[l,r]的数的xor值最大值。那么我们可以将这n个数分为sqrt(n)个块,我们设head[i]为第i个块的最开始元素,w[i][j]为从第i个块的第一个元素开始,到第j个数的区间中,任意找两个数的xor值最大,那么易得到转移方程w[i][j]=max(w[i][j],w[i][j-1]+query(head[i],j-1,a[j]))。这个的时间复杂度是o(sqrt(n)*n*logn)的,然后对于询问[l,r],我们设l后面第一个块为x块,那么ans=max(w[x][r],max(l,r,a[j])),j∈[l,head[x]-1]。

  备注:开始的时候以为题目说a[i]不会超过32767,后来发现好像是2147483647,然后改了trie的深度之后发现总是RE,因为我写的trie是先建一个空树,然后再插入节点的,31层的满二叉树当然没有办法建出来,那么改成了直接插入,发现还是WA,因为上一次的答案可能只比2147483647小一点,那么加上这次询问的值就会超过int,所以先强制转成long long然后%n就好了。

    开始以为RE是内存的问题,所以开大了好多,懒得改了就这样吧。

/**************************************************************
    Problem: 2741
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:8148 ms
    Memory:41680 kb
****************************************************************/
 
//By BLADEVIL
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 20000
#define maxm 400
 
using namespace std;
 
struct tree {
    int son[];
    int cnt;
    tree() {
        memset(son,,sizeof son);
        cnt=;
    }
}t[*maxn];
 
struct rec {
    int key,num,rot;
    rec() {
        key=num=rot=;
    }
}a[maxn];
 
int n,m,len,sum,tot;
int w[maxm][maxn],head[maxm];
 
void insert(int &x,int rot,int y,int dep) {
    if (!x) x=++tot;
    if (dep==-) {
        t[x].cnt=t[rot].cnt+;
        return ;
    }
    if (y&(<<dep)) {
        insert(t[x].son[],t[rot].son[],y,dep-);
        t[x].son[]=t[rot].son[];
    } else {
        insert(t[x].son[],t[rot].son[],y,dep-);
        t[x].son[]=t[rot].son[];
    }
    t[x].cnt=t[rot].cnt+;
}
 
int query(int lx,int rx,int y,int dep) {
    if (dep==-) return ;
    if (y&(<<dep)) {
        if (t[t[rx].son[]].cnt-t[t[lx].son[]].cnt)
            return (<<dep)+query(t[lx].son[],t[rx].son[],y,dep-); else
            return query(t[lx].son[],t[rx].son[],y,dep-);
    } else {
        if (t[t[rx].son[]].cnt-t[t[lx].son[]].cnt)
            return (<<dep)+query(t[lx].son[],t[rx].son[],y,dep-); else
            return query(t[lx].son[],t[rx].son[],y,dep-);
    }
}
 
int main() {
    scanf("%d%d",&n,&m);
    for (int i=;i<=n;i++) scanf("%d",&a[i].key);
    for (int i=;i<=n;i++) a[i].key^=a[i-].key;
    sum=len=sqrt(n); if (len*len<n) len++,sum=(n+len-)/len;
    //printf("%d %d\n",len,sum);
    for (int i=;i<=n;i++) if (!head[a[i].num=(i+len-)/len]) head[a[i].num]=i; head[sum+]=n+;
    //for (int i=1;i<=n;i++) printf("%d ",a[i].key); printf("\n");
    //for (int i=1;i<=sum;i++) printf("%d ",head[i]);
    for (int i=;i<=n;i++) insert(a[i].rot,a[i-].rot,a[i].key,);
    for (int i=;i<=sum;i++)
        for (int j=head[i];j<=n;j++)
            w[i][j]=max(w[i][j-],query(a[head[i]-].rot,a[j].rot,a[j].key,));
    /*
    for (int i=1;i<=sum;i++) {
        for (int j=1;j<=n;j++) printf("%d ",w[i][j]);
        printf("\n");
    }
    */
    int ans=;
    while (m--) {
        int l,r; scanf("%d%d",&l,&r); int x,y;
        x=((long long)l+ans)%n+; y=((long long)r+ans)%n+;
        l=min(x,y); r=max(x,y); ans=; l--;
        if (a[l].num==a[r].num) {
            for (int i=l;i<=r;i++) ans=max(ans,query(a[l-].rot,a[r].rot,a[i].key,));
        } else {
            ans=w[a[l].num+][r]; //printf("%d %d %d\n",ans,a[l].num+1,r);
            for (int i=l;i<=head[a[l].num+]-;i++) ans=max(ans,query(a[l-].rot,a[r].rot,a[i].key,));
        }
        printf("%d\n",ans);
    }
    return ;
}

bzoj 2741 可持久化trie的更多相关文章

  1. BZOJ - 3166 可持久化Trie 维护次大区间

    题意:给出\(a[1...n]\),找出一个连续区间\(a[l...r],r>l\),令该区间的次大值为\(a_k\),使得\(a_k⊕a_i,l≤i≤r\)最大,输出全局最优解 (这题意有点别 ...

  2. [BZOJ3261&BZOJ3166]可持久化trie树及其应用

    可持久化trie树 可持久化trie树现在想来是比较好理解的了,但却看了一个下午... 相当于对于每个状态建立一条链(或者说一棵trie),求解的时候只要让两个点按照相同的步子走然后看sum的大小关系 ...

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

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

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

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

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

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

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

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

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

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

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

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

  9. [BZOJ 4103] [Thu Summer Camp 2015] 异或运算 【可持久化Trie】

    题目链接:BZOJ - 4103 题目分析 THUSC滚粗之后一直没有写这道题,从来没写过可持久化Trie,发现其实和可持久化线段树都是一样的.嗯,有些东西就是明白得太晚. 首先Orz ZYF-ZYF ...

随机推荐

  1. windows远程连接设置

    1.设置整个服务器只允许一个连接. 使用组策略管理gpedit.msc, 计算机配置>管理模板>windows组件 >终端服务>限制连接数量,设为已启动,数量设置为1. 此设置 ...

  2. jenkins配置slave节点 构建项目并执行操作

    1.新建与配置结点 [系统管理]-> [管理结点]-> [新建结点] 2.配置slave 说明: Name: 定义slave的唯一名称标识,可以是任意字符串,通常设置为slave主机名.i ...

  3. web端调百度地图页面

    在点击进入地图的入口(下面数据是vue渲染的数据) <a class="navigation" v-if="merchant.longitude && ...

  4. 【.Net】Net开发

    博客里的好多文章都是本人看着比较好,就转过来的,好少自己亲自去写点什么,也很少把自己学的一点心得于大家分享,今天特别想聊一下,关于本人做Net开发时的那段回忆! 一.关于知识的回忆 还记得Handle ...

  5. 【JavaScript】jsp表格页面记录

    页面效果如下: jsp代码如下(里面引入了很多其他js文件,很多方法调用来自其他js): <%@ page language="java" contentType=" ...

  6. Shell脚本修改Nginx upstream配置文件

    #!/bin/bash ##################################################### # Name: change_nginx_upstream_conf ...

  7. POJ.3279 Fliptile (搜索+二进制枚举+开关问题)

    POJ.3279 Fliptile (搜索+二进制枚举+开关问题) 题意分析 题意大概就是给出一个map,由01组成,每次可以选取按其中某一个位置,按此位置之后,此位置及其直接相连(上下左右)的位置( ...

  8. bzoj3306: 树(dfs序+倍增+线段树)

    比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...

  9. bzoj2054: 疯狂的馒头(并查集)

    每个区间只被覆盖一次,求每个点被哪种区间覆盖或者某个区间是否已经被覆盖过都可以用并查集做. 做法:每个点都指向当前被覆盖区间的右端点+1的位置,某个点的下一个没被覆盖的点是gf(i),同理如果某个区间 ...

  10. python基础----常用模块

    一 time模块(时间模块)★★★★                                                      时间表现形式 在Python中,通常有这三种方式来表示时 ...