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

    Description

    FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和。
    即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r。
    为了体现在线操作,对于一个询问(x,y):
    l = min ( ((x+lastans) mod N)+1 , ((y+lastans) mod N)+1 ).
    r = max ( ((x+lastans) mod N)+1 , ((y+lastans) mod N)+1 ).
    其中lastans是上次询问的答案,一开始为0。

    Solution

    前缀异或和一下,然后就是求两个数的异或和最大,可以 (trie) 树上贪心
    考虑分块做
    块内可以预处理出 (f[i][j]) 表示块内的 (i),到 (j) 之间任选两个的异或和的最大值
    然后回答询问就直接用块内信息,块外多出来的长度 (<=sqrt{n}) 暴力求一遍就可以了

    #include<bits/stdc++.h>
    using namespace std;
    template<class T>void gi(T &x){
    	int f;char c;
    	for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
    	for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
    }
    typedef long long ll;
    const int N=12010;
    int n,m,b[N],B,s[N],cnt,rt[N],tt=0;ll f[205][N],a[N],bin[N];
    struct data{
    	int ls,rs,s;
    }tr[N*100];
    inline void ins(int &x,int d,ll w){
    	tr[++tt]=tr[x];x=tt;tr[x].s++;
    	if(d==-1)return ;
    	if(w&bin[d])ins(tr[x].rs,d-1,w);
    	else ins(tr[x].ls,d-1,w);
    }
    inline ll qry(int l,int r,int d,ll w){
    	if(d==-1)return 0;
    	if(w&bin[d]){
    		if(tr[tr[r].ls].s-tr[tr[l].ls].s)
    			return bin[d]+qry(tr[l].ls,tr[r].ls,d-1,w);
    		return qry(tr[l].rs,tr[r].rs,d-1,w);
    	}
    	else{
    		if(tr[tr[r].rs].s-tr[tr[l].rs].s)
    			return bin[d]+qry(tr[l].rs,tr[r].rs,d-1,w);
    		return qry(tr[l].ls,tr[r].ls,d-1,w);
    	}
    }
    int main(){
      freopen("pp.in","r",stdin);
      freopen("pp.out","w",stdout);
      cin>>n>>m;B=sqrt(n);cnt=n/B;
      for(int i=1;i<=n;i++)gi(a[i]),a[i]^=a[i-1];
      for(int i=0,t;i<=n;i++)b[i]=(t=i/B),s[t]=s[t]?s[t]:i;
      bin[0]=1;for(int i=1;i<=60;i++)bin[i]=bin[i-1]<<1;
      ins(rt[0],60,0);
      for(int i=1;i<=n;i++)rt[i]=rt[i-1],ins(rt[i],60,a[i]);
      for(int i=0;i<=cnt;i++){
    	  f[i][s[i]]=0;
    	  for(int j=s[i]+1;j<=n;j++)
    		  f[i][j]=max(f[i][j-1],qry(rt[s[i]-1],rt[j-1],60,a[j]));
      }
      ll x,y,ans=0;
      while(m--){
    	  gi(x);gi(y);x=(x+ans)%n+1;y=(y+ans)%n+1;
    	  if(x>y)swap(x,y);x--;ans=0;
    	  if(y-x+1<=B){
    		  for(int i=x;i<y;i++)ans=max(ans,qry(rt[i],rt[y],60,a[i]));
    		  printf("%lld
    ",ans);
    		  continue;
    	  }
    	  int t=s[b[x]]<x?b[x]+1:b[x];
    	  for(int i=t;i<=cnt && s[b[i]]<=y;i++)ans=max(ans,f[i][y]);
    	  for(int i=x;i<=s[t];i++)
    		  ans=max(ans,qry(rt[i],rt[y],60,a[i]));
    	  printf("%lld
    ",ans);
      }
      return 0;
    }
    
    
  • 相关阅读:
    python nltk nltk_data 离线安装,chatterbot
    ubuntu 16.04 64位 安装nvidia cuda
    发送imessage消息
    lua lor mongol socket.http
    pipenv
    headers参数格式化
    Linux删除空文件 空文件夹
    adb 操作安卓手机
    django 实现简单的检索功能
    1044: Access denied for user 'hehe'@'localhost' to database 'imooc'
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8992655.html
Copyright © 2011-2022 走看看