zoukankan      html  css  js  c++  java
  • bzoj3261: 最大异或和 可持久化字典树模板

    可持久化字典树不过记得是两次前缀和,所以记得减2,还有p=1的情况。

    #include<bits/stdc++.h>
    using namespace std;
    int l[18000000],r[18000000],sum[18000000],ans,a[600000],root[600000],n,m,cnt=0,l2,r2,x;
    char s[6];
    void add(int &rt,int pre,int val,int id)
    {
    	if(!rt)rt=++cnt;
    	sum[rt]=sum[pre]+1;
    	if(id<0)return;
    	l[rt]=l[pre];r[rt]=r[pre];
    	if(1<<(id)&val){r[rt]=0;add(r[rt],r[pre],val,id-1);}
    	else {l[rt]=0;add(l[rt],l[pre],val,id-1);}
    }
    void getmaxn(int L,int R,int id,int val)
    {
    	if(id<0)return;
    	if((1<<id)&val)
    	{
    		if(sum[l[R]]-sum[l[L]])
    		{
    			getmaxn(l[L],l[R],id-1,val);
    			ans|=(1<<id);
    		}
    		else
    		{
    			getmaxn(r[L],r[R],id-1,val);
    		}
    	}
    	else
    	{
    		if(sum[r[R]]-sum[r[L]])
    		{
    			getmaxn(r[L],r[R],id-1,val);
    			ans|=(1<<id);
    		}
    		else
    		{
    			getmaxn(l[L],l[R],id-1,val);
    		}
    	}
    }
    int main()
    {
    	//freopen("xf.in","r",stdin);
    	//freopen("xf.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){scanf("%d",&a[i]);a[i]^=a[i-1];add(root[i],root[i-1],a[i],25);}
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%s",s);
    		if(s[0]=='A')
    		{
    			scanf("%d",&a[++n]);
    			a[n]^=a[n-1];
    			add(root[n],root[n-1],a[n],25);
    		}
    		else
    		{
    			ans=0;
    			scanf("%d%d%d",&l2,&r2,&x);
    			getmaxn(root[max(l2-2,0)],root[r2-1],25,x^a[n]);
    			if(l2==1)ans=max(a[n]^x,ans);
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    C#: Create a WebRequest with HTTP Basic Authentication
    C# 集合
    BAT CMD 批处理文件脚本 -2
    年龄排序
    士兵买香蕉
    ACM交换生问题
    ACM卡片游戏
    ACM费马大定理
    ACM定外卖问题
    ACM汽车行程问题求最少的支付钱数
  • 原文地址:https://www.cnblogs.com/mybing/p/8794532.html
Copyright © 2011-2022 走看看