zoukankan      html  css  js  c++  java
  • BZOJ2741: 【FOTILE模拟赛】L

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2741

    分块+可持久化trie

    f[i][j]表示第i块到第j个数的最大答案。可以通过n^1.5时间内维护出来。

    然后对于询问就前面那一段暴力找和块的答案相比较就好了。

    然后似乎一定要插一个0 。。。

    #include<cstring>
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<set>
    #include<cmath>
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define maxn 20050
    #define inf int(1e9)
    #define maxd 30
    #define mm 1000000007
    #define ll long long
    using namespace std;
    int a[maxn];
    int f[130][maxn],s[maxn*301][2],sum[maxn*301],root[maxn],pos[maxn];
    int n,l,r,m,cnt,ans,len,num;
    int read(){
        int x=0,f=1; char ch=getchar();
        while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    void add(int d,int x,int &y,int val){
        y=++cnt; sum[y]=sum[x]+1; 
        if (d<0) return;
        s[y][0]=s[x][0]; s[y][1]=s[x][1];
        int p=(val>>d)&1;
        add(d-1,s[x][p],s[y][p],val);
    }
    int ask(int d,int x,int y,int val){
        if (d<0) return 0;
        int p=(val>>d)&1;
        if (sum[s[y][p^1]]-sum[s[x][p^1]]>0) return (1<<d)+ask(d-1,s[x][p^1],s[y][p^1],val);
        else return ask(d-1,s[x][p],s[y][p],val);
    }
    void getans(int l,int r){
        ans=0;
        int lx=pos[l],rx=pos[r];
        if (lx<rx) ans=f[lx+1][r];
        rep(i,l,min(lx*len,r)) ans=max(ans,ask(maxd,root[l],root[r+1],a[i]));
        printf("%d
    ",ans);
    }
    int main(){
        n=read(); m=read();
        len=sqrt(n);
        rep(i,1,n) a[i]=read(),a[i]=a[i]^a[i-1],pos[i]=i/len+1; 
        rep(i,0,n) add(maxd,root[i],root[i+1],a[i]);
        num=n/len+1;
        rep(i,1,num) {
            int now=(i-1)*len;
            rep(j,now,n) f[i][j]=max(f[i][j-1],ask(maxd,root[now],root[j+1],a[j]));
        }
        ans=0;
        rep(i,1,m){
            int x=read(),y=read();
            x=((ll)x+ans)%n+1; y=((ll)y+ans)%n+1;
            l=min(x,y); r=max(x,y);
            getans(l-1,r);
        }
        return 0;
    }
  • 相关阅读:
    基于php缓存的详解
    Nginx 的 Location 配置指令块
    Nginx负载均衡与反向代理的配置实例
    Linux下mysql定时备份及恢复
    KVO的底层实现
    小谈KVC中KeyPath的集合运算符
    iOS开发中常用的单例
    内存中的5大区域
    需要记住的几个ASCII码
    结构体-内存对齐
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5068205.html
Copyright © 2011-2022 走看看