zoukankan      html  css  js  c++  java
  • 最大异或和

    题意

    https://www.luogu.org/problem/P4735


    思路

    考虑查询操作,假设(s[i]=a[1]oplus a[2]oplus ...oplus a[i]),那么原式等价于(s[p-1]oplus s[n]oplus x)的最大值。

    我们可以维护一个可持久化trie树来解决。

    还是需要给这份代码打上注释啊。。。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    namespace StandardIO {
    
    	template<typename T>inline void read (T &x) {
    		x=0;T f=1;char c=getchar();
    		for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
    		for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
    		x*=f;
    	}
    
    	template<typename T>inline void write (T x) {
    		if (x<0) putchar('-'),x*=-1;
    		if (x>=10) write(x/10);
    		putchar(x%10+'0');
    	}
    
    }
    
    using namespace StandardIO;
    
    namespace Project {
    	
    	const int N=600600; // 之所以要开两倍是因为还有插入操作,两次RE都在这里。
    	
    	int n,m;
    	int s[N];
    	struct Trie {
    		int tot;
    		int root[N];
    		int ch[N*24][2],latest[N*24]; // latest数组用来限制左边界。
    		
    		void insert (int left,int pos,int last,int cur) {
                            latest[cur]=left; // 更新左边界。
    			if (pos==-1) return ; // 如果遍历完01串了就结束递归。
    			int o=(s[left]>>pos)&1; // 取出当前位。
    			if (last) ch[cur][o^1]=ch[last][o^1]; // 没有被更新的一遍原样继承即可。
    			ch[cur][o]=++tot; // 新建节点。
    			insert(left,pos-1,ch[last][o],ch[cur][o]); // 递归。
    		}
    		int query (int left,int pos,int v,int cur) { // 按照贪心的思路向下走,每次尽量选取相反的孩子。
    			if (pos==-1) return s[latest[cur]]^v; // 返回答案。
    			int o=(v>>pos)&1; // 取出当前位。
    			if (latest[ch[cur][o^1]]>=left) return query(left,pos-1,v,ch[cur][o^1]); // 如果相反位可以取(即当前情况下存在),那么选择。
    			return query(left,pos-1,v,ch[cur][o]); // 否则选择相同位。
    		}
    	} trie;
    
    	inline void MAIN () {
    		read(n),read(m);
    		trie.latest[0]=-1,trie.root[0]=++trie.tot;
    		trie.insert(0,23,0,trie.root[0]);
    		for (register int i=1; i<=n; ++i) {
    			read(s[i]),s[i]^=s[i-1];
    			trie.root[i]=++trie.tot,trie.insert(i,23,trie.root[i-1],trie.root[i]);
    		}
    		for (register int i=1; i<=m; ++i) {
    			char op;int l,r,x;
    			cin>>op;
    			if (op=='A') {
    				read(x),trie.root[++n]=++trie.tot,s[n]=s[n-1]^x;
    				trie.insert(n,23,trie.root[n-1],trie.root[n]);
    			} else {
    				read(l),read(r),read(x);
    				write(trie.query(l-1,23,s[n]^x,trie.root[r-1])),putchar('
    ');
    			}
    		}
    	}
    	
    }
    
    int main () {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	Project::MAIN();
    }
    
    
  • 相关阅读:
    Spring Boot 的各种start
    Lombok介绍、使用方法和总结
    JS字符串与二进制的相互转化
    java字符串与二进制的相互转化
    DevExpress WPF v18.2新版亮点(六)
    用MyEclipse开发REST Web Service
    .NET界面控件DevExpress发布v18.2.4|附下载
    DevExpress WPF v18.2新版亮点(五)
    「版本升级」MyEclipse CI 2018.12.0正式发布
    MyEclipse使用教程:在Web项目中使用Web片段
  • 原文地址:https://www.cnblogs.com/ilverene/p/11618617.html
Copyright © 2011-2022 走看看