• 题解:2019十二省联考 异或粽子


    题意:

    求前k大连续子段异或和

    1. 做前缀异或和,然后变成求最大的k对异或和的和
    2. 可以对每一个i求出第t(初始为1)大的$a_i xor a_j$,然后把结果扔到堆里,每次取堆顶,然后把堆顶对应的i的第t+1大的$a_i xor a_j$扔进堆里

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    using namespace std;
    
    #define re register
    #define ll long long
    #define gc getchar()
    inline ll read()
    {
     	re ll x(0);re char c(gc);
        while(c>'9'||c<'0') c=gc;
        while(c>='0'&&c<='9')x=x*10+c-48,c=gc;
        return x;
    }
    
    const int N=2e7+10; 
    ll n,k,a[N][2],siz[N],m,tot;
    ll ans=1,x,s[N];
    struct node {int id,rk;ll w;};
    bool operator < (node a,node b){return a.w<b.w;} 
    priority_queue<node> q;
    
    void ins(ll x)
    {
    	int u=0;
    	for(int i=31;i>=0;--i)
    	{
    		int ch=(x>>i)&1;siz[u]++;
    		if(!a[u][ch]) a[u][ch]=++tot;
    		u=a[u][ch];
    	}
    	siz[u]++; 
    }
    ll query(ll x,int rk)
    {
    	int u=0;ll an=0;
    	for(int i=31;i>=0;--i)
    	{
    		int ch=(x>>i)&1;
    		if(!a[u][ch^1]) u=a[u][ch];
    		else if(rk<=siz[a[u][ch^1]])
    			u=a[u][ch^1],an|=1LL<<i;
    		else 
    			rk-=siz[a[u][ch^1]],u=a[u][ch];
    	}
    	return an;
    }
    
    int main()
    {
    	n=read(),k=read(),k<<=1;
    	for(int i=1;i<=n;++i) x=read(),s[i]=s[i-1]^x;
    	for(int i=0;i<=n;++i) ins(s[i]);
    	for(int i=0;i<=n;++i) q.push((node){i,1,query(s[i],1)});
    	for(int i=1;i<=k;++i)
    	{
    		node u=q.top();
    		ans+=u.w;q.pop();
    		if(u.rk<n) q.push((node){u.id,u.rk+1,query(s[u.id],u.rk+1)});
    	}
    	cout<<(ans>>1)<<endl; 
    	return 0;
    }
    

      

  • 相关阅读:
    详解单例模式
    Spring整合Mybatis案例,献给初学的朋友
    Java反射学习总结
    IDEA JSP项目构建及学习心得
    SQL Server数据库表锁定原理以及如何解除表的锁定
    MySQL锁定机制简介
    Cassandra简介
    Linux机器上实现程序自动部署以及更新
    服务器时间同步平台化
    内存查看平台化
  • 原文地址:https://www.cnblogs.com/zijinjun/p/10778580.html
Copyright © 2020-2023  润新知