zoukankan      html  css  js  c++  java
  • 【洛谷5283】[十二省联考2019] 异或粽子(可持久化Trie树+堆)

    点此看题面

    大致题意: 求前(k)大的区间异或和之和。

    可持久化(Trie)

    之前做过一些可持久化(Trie)树题,结果说到底还是主席树。

    终于,碰到一道真·可持久化(Trie)的题目。

    其实它的实现与主席树也是类似的。

    大致思路

    首先,我们统计一遍前缀异或和。

    然后,我们根据前缀异或和建一棵可持久化(Trie)树。

    接下来最核心的来了:

    我们先求出以每个点为右端点所能得到的最大异或和,这可以在(Trie)树上查询得到(和普通的(Trie)树是一样的)。

    然后,把这些值连同该右端点全扔入大根堆里。

    每次,我们取出堆顶,统计答案后求出以该点为右端点所能得到的次大值,然后重新扔入堆里。如果再取到该右端点,就是次次大值、次次次大值,以此类推。

    那么如何求次大值呢?

    没关系,反正我们本来就是可持久化(Trie)树,直接复制该点的(Trie)树并将求出的最大值所对应的数在树上删去即可。

    这种方法的复杂度应该是(O((n+k)log Max a_i)),但我写得弱了一点,变成了(O((2n+k)log Max a_i))。虽然很好改,但我懒得改了。。。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define RU Reg unsigned
    #define Con const
    #define CI Con int&
    #define CU Con unsigned&
    #define I inline
    #define W while
    #define N 500000
    #define K 200000
    #define mp make_pair
    #define fir first
    #define sec second
    using namespace std;
    int n,k,p[N+5];unsigned a[N+5];typedef pair<unsigned,int> Pr;
    priority_queue<Pr> q;
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define tn (x<<3)+(x<<1)
    		#define D isdigit(c=tc())
    		char c,*A,*B,FI[FS];
    	public:
    		I FastIO() {A=B=FI;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
    		Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
    		#undef D
    }F;
    class PersistentTrie//可持久化Trie树
    {
    	private:
    		#define SZ ((N<<1)+K+1)
    		#define Log 33
    		int tot,Rt[N+5];struct node {int Sz,S[2];}O[SZ*Log+5];
    		I void upt(int& rt1,RI rt2,CU x,CI t,CI D)//修改
    		{
    			if((O[rt1=++tot]=O[rt2]).Sz+=t,!~D) return;//复制节点,更新size
    			RI d=(x>>D)&1;upt(O[rt1].S[d],O[rt2].S[d],x,t,D-1);//处理子节点
    		}
    		I unsigned qry(int& rt,CI x,CI D)//询问与x的最大异或和
    		{
    			if(!~D) return 0;RI d=(x>>D)&1;
    			return O[O[rt].S[d^1]].Sz?qry(O[rt].S[d^1],x,D-1)|(1<<D):qry(O[rt].S[d],x,D-1);//能使这一位为1就必使其为1,否则使其为0
    		}
    	public:
    		I PersistentTrie() {tot=1,Update(0,0,0,1);}
    		I void Update(CI v1,CI v2,CU x,CI t) {upt(Rt[v1],Rt[v2],x,t,31);}
    		I unsigned Query(CI v) {RU t=qry(Rt[v],a[v],31);return Update(v,v,a[v]^t,-1),t;}//询问,为避免计算多次贡献将其删去
    }P;
    int main()
    {
    	RI i;Pr t;Reg long long ans=0;
    	for(F.read(n,k),i=1;i<=n;++i) F.read(a[p[i]=i]),a[i]^=a[i-1],P.Update(i,i-1,a[i],1);//初始化建树
    	for(i=1;i<=n;++i) q.push(mp(P.Query(i),i));//询问然后扔入堆中
    	for(i=1;i<=k;++i) t=q.top(),q.pop(),ans+=t.fir,//取出堆顶,统计答案
    		--p[t.sec]&&(q.push(mp(P.Query(t.sec),t.sec)),0);//将次大值扔入堆中
    	return printf("%lld",ans),0;//输出答案
    }
    
  • 相关阅读:
    使用tcmalloc编译启动时宕机
    使用tcmalloc编译出现undefined reference to `sem_init'
    使用AddressSanitizer做内存分析(一)——入门篇
    VIM-美化你的标签栏
    Entity Framework Code First (六)存储过程
    Entity Framework Code First (五)Fluent API
    Entity Framework Code First (四)Fluent API
    Entity Framework Code First (三)Data Annotations
    Entity Framework Code First (二)Custom Conventions
    Entity Framework Code First (一)Conventions
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu5283.html
Copyright © 2011-2022 走看看