zoukankan      html  css  js  c++  java
  • LOJ#3048. 「十二省联考 2019」异或粽子(trie树+堆)

    题面

    传送门

    题解

    我们先把它给前缀异或和一下,然后就是要求前(k)大的(a_ioplus a_j)。把(k)乘上个(2),变成前(2k)大的(a_ioplus a_j),最后答案除以一个(2)就可以了。显然(a_ioplus a_i=0),所以并不会影响答案

    我们开一个堆,存((i,k))表示对于(a_i)来说,第(k)大的(a_ioplus a_j)的值,然后每次把((i,k+1))扔进堆里就可以了

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ll long long
    #define inline __inline__ __attribute__((always_inline))
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    ll read(){
        R ll res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=5e5+5,M=N*35+5;
    ll res=1,s[N];int ch[M][2],sz[M],n,m,tot;
    struct node{
    	int u,k;ll s;
    	inline node(R int uu,R int kk,R ll ss):u(uu),k(kk),s(ss){}
    	inline bool operator <(const node &b)const{return s<b.s;}
    };priority_queue<node>q;
    void ins(ll c){
    	for(R int i=31,p=0,t;~i;--i){
    		t=c>>i&1;
    		if(!ch[p][t])ch[p][t]=++tot;
    		p=ch[p][t],++sz[p];
    	}
    }
    ll query(ll c,int k){
    	ll res=0;
    	for(R int i=31,p=0,t;~i;--i){
    		t=c>>i&1;
    		sz[ch[p][t^1]]>=k?(res|=(1ll<<i),p=ch[p][t^1]):(k-=sz[ch[p][t^1]],p=ch[p][t]);
    	}
    	return res;
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),m=read()<<1,ins(0);
    	fp(i,1,n)s[i]=s[i-1]^read(),ins(s[i]);
    	fp(i,0,n)q.push(node(i,1,query(s[i],1)));
    	while(m--){
    		int u=q.top().u,k=q.top().k;res+=q.top().s;q.pop();
    		if(k<n)q.push(node(u,k+1,query(s[u],k+1)));
    	}
    	printf("%lld
    ",res>>1);
    	return 0;
    }
    
  • 相关阅读:
    【今日CV 视觉论文速览】 19 Nov 2018
    【numpy求和】numpy.sum()求和
    【今日CV 视觉论文速览】16 Nov 2018
    【今日CV 视觉论文速览】15 Nov 2018
    poj 2454 Jersey Politics 随机化
    poj 3318 Matrix Multiplication 随机化算法
    hdu 3400 Line belt 三分法
    poj 3301 Texas Trip 三分法
    poj 2976 Dropping tests 0/1分数规划
    poj 3440 Coin Toss 概率问题
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10746117.html
Copyright © 2011-2022 走看看