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

    题意

    先分块,预处理(f_{i,j})表示从第(i)块的开头到第(j)个数的答案,之后就是分块的套路了。
    注意(l,r)加的时候会爆int。
    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int maxn=12010;
    const int maxt=150;
    int n,m,t,cnt,tot,lastans;
    int a[maxn],sum[maxn],L[maxt],R[maxt],pos[maxn],root[maxn],last[maxn*40];
    int f[maxt][maxn],trie[maxn*40][2];
    void insert(int pre,int now,int k,int val,int id)
    {
    	if(k<0){last[now]=id;return;}
    	int c=(val>>k)&1;
    	if(pre)trie[now][c^1]=trie[pre][c^1];
    	trie[now][c]=++tot;
    	insert(trie[pre][c],trie[now][c],k-1,val,id);
    	last[now]=max(last[trie[now][0]],last[trie[now][1]]);
    }
    int query(int now,int k,int val,int lim)
    {
    	if(k<0)return 0;
    	int c=(val>>k)&1;
    	if(last[trie[now][c^1]]>=lim)return (1<<k)+query(trie[now][c^1],k-1,val,lim);
    	else return query(trie[now][c],k-1,val,lim);
    }
    inline void pre_work()
    {
    	root[0]=++tot,last[0]=-1;insert(0,root[0],35,0,0);
    	for(int i=1;i<=n;i++)root[i]=++tot,insert(root[i-1],root[i],35,sum[i],i);
    	t=(int)sqrt(n)+1;cnt=n/t;
    	if(n%t)cnt++;
    	for(int i=1;i<=cnt;i++)L[i]=(i-1)*t+1,R[i]=min(i*t,n);
    	for(int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    	for(int i=1;i<=cnt;i++)
    	{
    		f[i][L[i]]=0;
    		for(int j=L[i]+1;j<=n;j++)f[i][j]=max(f[i][j-1],query(root[j-1],35,sum[j],L[i]));
    	}
    }
    inline int query(int ql,int qr)
    {
    	int res=0;
    	if(pos[ql]==pos[qr])
    	{
    		for(int i=ql;i<=qr;i++)res=max(res,query(root[qr],35,sum[i-1],i));
    		return res;
    	}
    	int p=L[pos[ql]]<ql?pos[ql]+1:pos[ql];
    	res=f[p][qr];
    	for(int i=ql;i<=L[p];i++)res=max(res,query(root[qr],35,sum[i-1],i));
    	return res;
    }
    signed main()
    {
    	//freopen("test.in","r",stdin);
    	//freopen("test.out","w",stdout);
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;i++)scanf("%lld",&a[i]),sum[i]=sum[i-1]^a[i];
    	pre_work();
    	for(int i=1;i<=m;i++)
    	{
    		int l,r,x,y;scanf("%lld%lld",&x,&y);
    		l=min((x+lastans)%n+1,(y+lastans)%n+1),r=max((x+lastans)%n+1,(y+lastans)%n+1);
    		printf("%lld
    ",lastans=query(l,r));
    	}
    	return 0;
    }
    
  • 相关阅读:
    采用坐标变换(移动和旋转)画箭头
    学会Func
    一个链接器的实现
    linux内核skb操作
    终于实现samba可写不可删除
    删掉SafeDrv病毒(这个病毒有点意思)
    Writing a ServiceMain Function(使用RegisterServiceCtrlHandler函数)
    利用Winscp,Putty实现Windows下编写Linux程序
    联发科6亿美元将大陆子公司卖给四维图新(180个人价值6亿美元)
    TFTP:简单文本传输协议,BOOTP:引导程序协议
  • 原文地址:https://www.cnblogs.com/nofind/p/12015310.html
Copyright © 2011-2022 走看看