zoukankan      html  css  js  c++  java
  • 【BZOJ3689】异或之(可持久化Trie树)

    点此看题面

    大致题意: 给定(n)个数,让你求两两异或和的前(k)小值。

    双倍经验

    这道题和【洛谷5283】[十二省联考2019] 异或粽子是完全一样的,甚至比那题还少一个虽说挺简单的转化。

    这里就直接贴代码了。

    代码

    #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 100000
    #define K 250000
    #define LN 30
    using namespace std;
    int n,k,a[N+5];
    struct data
    {
    	int p,v;I data(CI x=0,CI y=0):p(x),v(y){}
    	I bool operator > (Con data& o) Con {return v>o.v;}
    };priority_queue<data,vector<data>,greater<data> > q;
    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);}
    		Tp I void write(Ty x,Con char& y) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);pc(y);}
    		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+K)*(LN+2)+5];
    		I void U(int& x,RI y,CI v,CI k,CI d)//修改
    		{
    			(O[x=++Nt]=O[y]).Sz+=k;if(!~d) return;
    			U(O[x].S[(v>>d)&1],O[y].S[(v>>d)&1],v,k,d-1);
    		}
    		I int Q(CI rt,CI v,CI d)//询问
    		{
    			if(!~d) return 0;RI t=(v>>d)&1;
    			if(O[O[rt].S[t]].Sz) return Q(O[rt].S[t],v,d-1);//贪心选0
    			return Q(O[rt].S[t^1],v,d-1)|(1<<d);
    		}
    	public:
    		I void U(CI v,CI lst,CI x,CI y) {U(Rt[v],Rt[lst],x,y,LN);}
    		I int Q(CI v,CI x) {return O[Rt[v]].Sz?Q(Rt[v],x,LN):-1;}
    }T;
    int main()
    {
    	RI i;for(F.read(n),F.read(k),i=1;i<=n;++i) F.read(a[i]),T.U(i,i-1,a[i],1);
    	for(i=2;i<=n;++i) q.push(data(i,T.Q(i-1,a[i])));//初始化堆
    	RI v;data t;for(i=1;i<=k;++i) t=q.top(),q.pop(),F.write(t.v," 
    "[i==k]),//取出堆顶输出
    		T.U(t.p-1,t.p-1,a[t.p]^t.v,-1),~(v=T.Q(t.p-1,a[t.p]))&&(q.push(data(t.p,v)),0);//找到新的最小值
    	return F.clear(),0;
    }
    
  • 相关阅读:
    C# Winform中WndProc 函数作用
    C#程序集编译输出XML文档的作用
    C#属性访问器
    C#索引器
    static修饰符
    abstract 与 interface
    使用 Override 和 New 关键字进行版本控制
    scrapy爬虫初体验
    正则表达式
    MySQL常用指令
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ3689.html
Copyright © 2011-2022 走看看