zoukankan      html  css  js  c++  java
  • BZOJ 2741 【FOTILE模拟赛】L

     题意:强制在线多次询问区间[l,r]内的最大连续异或和.

     题解:

     对序列进行前缀异或和,将问题转化成求区间[l-1,r]中的最大的两数异或和.

     两个数的限制十分麻烦,尝试分块.

     预处理数组f[i][j]表示第i块的最左端到j的这段区间最大的两数异或和.

     显然这个数组可以在O(sqrt(n)*n*32)的时间中算出来.32是因为我们需要用到可持久化Trie.

     对于每个询问.

     如果询问的区间中含有块的左端点,利用f数组直接递推出剩下的答案.否则暴力算即可.

     时间复杂度O(sqrt(n)*n*logw+sqrt(n)*m*log);

     代码复杂度低.

     没有去掉打表,WA了一次,遗憾.

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define FILE "dealing"
     5 #define up(i,j,n) for(int i=j;i<=n;i++)
     6 #define db long double 
     7 #define pii pair<int,int>
     8 #define pb push_back
     9 #define mem(a,L) memset(a,0,sizeof(int)*(L+1))
    10 template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;}
    11 template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;}
    12 template<class T> inline T squ(T a){return a*a;}
    13 const ll maxn=2000100+10,MAXN=20200,mod=1e9+7,limit=1e7,base=23;
    14 int read(){
    15     int x=0,f=1,ch=getchar();
    16     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    17     while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    18     return x*f;
    19 }
    20 int n,m;
    21 int a[MAXN],root[MAXN],c[maxn][2],sum[maxn],cnt,blo,f[200][12100];
    22 void updata(int o){
    23     sum[o]=sum[c[o][0]]+sum[c[o][1]];
    24 }
    25 void insert(int pre,int& o,int key,int dep){
    26     o=++cnt;
    27     if(dep==-1){
    28         sum[o]=sum[pre]+1;
    29         return;
    30     }
    31     if(key&(1<<dep))c[o][0]=c[pre][0],insert(c[pre][1],c[o][1],key,dep-1);
    32     else c[o][1]=c[pre][1],insert(c[pre][0],c[o][0],key,dep-1);
    33     updata(o);
    34 }
    35 int ask(int pre,int o,int key,int k,int dep){
    36     if(dep==-1)return key;
    37     int d=(k&(1<<dep))?1:0;
    38     if(sum[c[o][d^1]]-sum[c[pre][d^1]])return ask(c[pre][d^1],c[o][d^1],key|(1<<dep),k,dep-1);
    39     else return ask(c[pre][d],c[o][d],key,k,dep-1);
    40 }
    41 int main(){
    42     freopen(FILE".in","r",stdin);
    43     freopen(FILE".out","w",stdout);
    44     n=read(),m=read();
    45     up(i,1,n)a[i]=read()^a[i-1];
    46     up(i,0,n)insert((!i)?0:root[i-1],root[i],a[i],30);
    47     blo=(int)sqrt(n+1.0)+1;
    48     for(int i=0;i<=n;i+=blo)
    49         for(int j=i+1;j<=n;j++)
    50             f[i/blo][j]=max(f[i/blo][j-1],ask((!i)?0:root[i-1],root[j-1],0,a[j],30));
    51     ll lastans=0;
    52     up(i,1,m){
    53         int x=read(),y=read(),l,r;
    54         l=min(((ll)x+lastans)%n+1,((ll)y+lastans)%n+1)-1;
    55         r=max(((ll)x+lastans)%n+1,((ll)y+lastans)%n+1);
    56         int s=l;
    57         while(s%blo&&s<n&&s<r)s++;
    58         if(s==r){
    59             int ans=0;
    60             for(int j=l+1;j<=r;j++)
    61                 cmax(ans,ask((!l)?0:root[l-1],root[j-1],0,a[j],30));
    62             printf("%lld
    ",lastans=ans);
    63         }
    64         else {
    65             int ans=f[s/blo][r];
    66             for(int j=s-1;j>=l;j--)
    67                 cmax(ans,ask(root[j],root[r],0,a[j],30));
    68             printf("%lld
    ",lastans=ans);
    69         }
    70     }
    71     return 0;
    72 }
    View Code

     

  • 相关阅读:
    这几天都是在公司慢待
    电脑没有关机可能出现发博文dns异常(write)
    DOS/VBS
    SourceInsight
    CevaEclipse
    C/C++
    Matlab
    Matlab
    C语言
    Matlab
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6811638.html
Copyright © 2011-2022 走看看