# bzoj2741【FOTILE模拟赛】L

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

$g[i][j]$表表示第i块中某一个数与第j块中某一个数异或（即b[l[i]...r[i]]中的某一个数异或与b[l[j]...r[j]]中的某一个数异或），得到的最大的异或和是多少。这个可以在$O(N\sqrt{N})$从F数组得到。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ，但不适用于poj

using namespace std;

typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP;

#define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define fill(a,l,r,v) fill(a+l,a+r+1,v)
#define re(i,a,b)  for(i=(a);i<=(b);i++)
#define red(i,a,b) for(i=(a);i>=(b);i--)
#define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define p_b(a) push_back(a)
#define SF scanf
#define PF printf
#define two(k) (1<<(k))

template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}

const DB EPS=1e-9;
inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
const DB Pi=acos(-1.0);

inline int gint()
{
int res=0;bool neg=0;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return 0;
if(z=='-'){neg=1;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
return (neg)?-res:res;
}
inline LL gll()
{
LL res=0;bool neg=0;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return 0;
if(z=='-'){neg=1;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
return (neg)?-res:res;
}

const int maxN=12000;
const int maxcnt=120;

struct Tnode
{
Tnode *son[2];
inline Tnode(){son[0]=son[1]=0;}
};

int N,Q;
int len,cnt,id[maxN+10],l[maxcnt+10],r[maxcnt+10];
int a[maxN+100];
Tnode *rt[maxcnt+10];
int f[maxN+100][maxcnt+10];
int g[maxcnt+100][maxcnt+10];
int lastans;

int t[40];
inline void insert(Tnode *p,int v)
{
int i;
re(i,1,31)t[i]=v&1,v>>=1;
red(i,31,1)
{
if(!p->son[t[i]])p->son[t[i]]=new Tnode;
p=p->son[t[i]];
}
}
inline int find(Tnode *p,int v)
{
int i,res=0;
re(i,1,31)t[i]=v&1,v>>=1;
red(i,31,1)
{
int to=(p->son[t[i]^1])?t[i]^1:t[i];
res=(res<<1)+to;
p=p->son[to];
}
return res;
}

int main()
{
freopen("bzoj2741.in","r",stdin);
freopen("bzoj2741.out","w",stdout);
int i,j;
N=gint()+1;Q=gint();
re(i,2,N)a[i]=gint();
re(i,1,N)a[i]^=a[i-1];
len=int(sqrt(DB(N)));
re(i,1,N)
{
if((i-1)%len==0)r[cnt]=i-1,l[++cnt]=i;
id[i]=cnt;
}
r[cnt]=N;
re(i,1,cnt)rt[i]=new Tnode;
re(i,1,N)insert(rt[id[i]],a[i]);
re(i,1,N)re(j,1,cnt)f[i][j]=a[i]^find(rt[j],a[i]);
re(i,1,N)re(j,1,cnt)upmax(g[id[i]][j],f[i][j]);
lastans=0;
while(Q--)
{
int x=gint(),y=gint();
int L=int( min( (LL(x)+LL(lastans))%LL(N-1)+1 , (LL(y)+LL(lastans))%LL(N-1)+1 ) ) +1 ;
int R=int( max( (LL(x)+LL(lastans))%LL(N-1)+1 , (LL(y)+LL(lastans))%LL(N-1)+1 ) ) +1 ;
L--;
lastans=0;
if(id[L]==id[R] || id[L]+1==id[R])
{
re(i,L,R)re(j,i,R)upmax(lastans,a[i]^a[j]);
}
else
{
int p=(L==l[id[L]])?id[L]:id[L]+1,q=(R==r[id[R]])?id[R]:id[R]-1;
re(i,p,q)re(j,i,q) upmax(lastans,g[i][j]);
re(i,L,l[p]-1)re(j,p,q) upmax(lastans,f[i][j]);
re(i,r[q]+1,R)re(j,p,q) upmax(lastans,f[i][j]);
re(i,L,l[p]-1)re(j,r[q]+1,R)upmax(lastans,a[i]^a[j]);
re(i,L,l[p]-1)re(j,i+1,l[p]-1)upmax(lastans,a[i]^a[j]);
re(i,r[q]+1,R)re(j,i+1,R)upmax(lastans,a[i]^a[j]);
}
cout<<lastans<<endl;
}
return 0;
}
View Code

posted @ 2015-08-29 10:38  maijing  阅读(231)  评论(0编辑  收藏  举报