zoukankan      html  css  js  c++  java
  • 【BZOJ3261】最大异或和(可持久化Trie树水题)

    点此看题面

    大致题意: 给定一个序列,要求支持两种操作:在序列末尾加一个数;询问后缀(lsim r)(x)的最大异或和。

    前言

    因为某比赛亡在一道水题上,于是悲愤地找了道水题刷刷。

    后缀变前缀

    一开始(naive)地想要维护后缀和,结果没搞出来(我也不知道实际上究竟行不行)。

    后来突然想到后缀异或和就等于前缀异或和异或上整个序列的异或和,于是这道题就变成(SB)题了。

    直接套个可持久化(Trie)树的板子,再开个变量记一下整个序列的异或和,把每次询问给的数异或上整个序列的异或和再询问,就完事了。

    这种水题也懒得多说什么了,直接上代码吧。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 600000
    #define LN 30
    using namespace std;
    int n;
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define pc(c) (C==E&&(clear(),0),*C++=c)
    		#define D isdigit(c=tc())
    		int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
    	public:
    		I FastIO() {A=B=FI,C=FO,E=FO+FS;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=(x<<3)+(x<<1)+(c&15),D);}
    		I void readc(char& x) {W(isspace(x=tc()));}
    		Tp I void writeln(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);pc('
    ');}
    		I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
    }F;
    class Trie
    {
    	private:
    		int Nt,Rt[N+5];struct node {int Sz,S[2];}O[(N+1)*(LN+1)+5];
    		I void Ins(int& x,CI y,CI v,CI d)//插入
    		{
    			++(O[x=++Nt]=O[y]).Sz;if(!~d) return;RI t=(v>>d)&1;
    			Ins(O[x].S[t],O[y].S[t],v,d-1);
    		}
    		I int Qry(CI x,CI y,CI v,CI d)//询问
    		{
    			if(!~d) return 0;RI t=(v>>d)&1^1;
    			if(O[O[x].S[t]].Sz^O[O[y].S[t]].Sz) return Qry(O[x].S[t],O[y].S[t],v,d-1)|(1<<d);
    			return Qry(O[x].S[t^1],O[y].S[t^1],v,d-1);
    		}
    	public:
    		I void Ins(CI v,CI x) {Ins(Rt[v],Rt[v-1],x,LN);}
    		I int Qry(CI l,CI r,CI v) {return Qry(Rt[l-1],Rt[r],v,LN);}
    }T;
    int main()
    {
    	RI Qt,i,x,y,z,s=0;char op;T.Ins(1,0);//注意,这里把0的前缀作为第一个版本,不然可能导致询问版本-1越界
    	for(F.read(n),F.read(Qt),i=1;i<=n;++i) F.read(x),T.Ins(i+1,s^=x);//读入初始序列插入树中
    	W(Qt--) switch(F.readc(op),op)
    	{
    		case 'A':F.read(x),T.Ins((++n)+1,s^=x);break;//加数
    		case 'Q':F.read(x),F.read(y),F.read(z),F.writeln(T.Qry(x,y,s^z));break;//处理询问
    	}return F.clear(),0;
    }
    
  • 相关阅读:
    centos6.5 源码安装 gtk 环境
    世界的复杂性
    将 shell 脚本打包到 rpm 包中
    使用 ipdb 调试 Python
    shell 处理 文件名本身带星号的情况
    如果可以更更完善,为什么不呢?
    比较有名的开源项目
    各种小工具合集
    各种版本对应关系
    dns相关
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ3261.html
Copyright © 2011-2022 走看看