• BZOJ2741 【FOTILE模拟赛】L


    题目描述:

    对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r。(强制在线)

    题解:

    可持久化Trie+分块。

    分块处理当前块上某点为起点,块后任一点为终点的最大异或和。

    代码:

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 12050
    #define M 6050
    inline int rd()
    {
        int f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n,m,a[N],rt[N],ans=0,wt;
    struct Trie
    {
        int tot,siz[35*N],ch[35*N][2];
        int insert(int now,int x)
        {
            int u,ret,f=rt[now-1];
            u=ret=++tot;
            for(int i=30;i>=0;i--)
            {
                ch[u][0]=ch[f][0],ch[u][1]=ch[f][1],siz[u]=siz[f]+1;
                int c = (x>>i)&1;
                ch[u][c]=++tot;
                u=ch[u][c],f=ch[f][c];
            }
            siz[u]=siz[f]+1;
            return ret;
        }
        int query(int l,int r,int x)
        {
            l=rt[l],r=rt[r];
            int ret = 0;
            for(int i=30;i>=0;i--)
            {
                int c = (x>>i)&1;
                if(siz[ch[r][!c]]-siz[ch[l][!c]])
                {
                    ret|=(1<<i);
                    l=ch[l][!c],r=ch[r][!c];
                }else l=ch[l][c],r=ch[r][c];
            }
            return ret;
        }
    }tr;
    int f[N][150],bel[N];
    int main()
    {
        n=rd()+1,m=rd();
        rt[1]=tr.insert(1,0);
        for(int i=2;i<=n;i++)
        {
            a[i]=rd()^a[i-1];
            rt[i]=tr.insert(i,a[i]);
        }
        wt=(int)sqrt(n);
        for(int i=1;i<=n;i++)
            bel[i]=(i-1)/wt;
        for(int j=0;j<=(n-1)/wt;j++)
        {
            int l = j*wt,r = min((j+1)*wt,n);
            for(int i=l+1;i<=n;i++)
            {
                f[i][j]=max(f[i-1][j],tr.query(l,r,a[i]));
            }
        }
        while(m--)
        {
            int l=(int)((1ll*rd()+1ll*ans)%(n-1)+1);
            int r=(int)((1ll*rd()+1ll*ans)%(n-1)+1);
            if(l>r)swap(l,r);
            ans=0;
            r++;
            if(bel[l]==bel[r])
            {
                for(int i=l;i<=r;i++)
                    ans=max(ans,tr.query(l-1,r,a[i]));
            }else
            {
                for(int i=l;bel[i]==bel[l];i++)
                    ans=max(ans,tr.query(l-1,r,a[i]));
                for(int i=r;bel[i]==bel[r];i--)
                    ans=max(ans,tr.query(l-1,r,a[i]));
                for(int i=bel[l]+1;i<bel[r];i++)
                    ans=max(ans,f[r][i]);
            }
            printf("%d
    ",ans);
        }
    
        return 0;
    }
  • 相关阅读:
    for循环使用详解(c语言版)
    在Spring中轻松写日志
    项目可行性分析的困难
    控制台游戏引擎CGE——贪吃蛇
    python做数据分析pandas库介绍之DataFrame基本操作
    什么是 JWT -- JSON WEB TOKEN
    .net core 单体应用基于策略模式授权
    ABP VNext 初始化数据库时报错
    ABP VNext简介及使用代码生成器ABPHelper自动生成代码
    使用jenkins 在docker中发布.net core应用
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10046336.html
Copyright © 2020-2023  润新知