• P5283 [十二省联考2019]异或粽子


    传送门

    超级钢琴+可持久化$Trie$

    同样设三元组 $(o,l,r)$ 表示左端点为 $o$,右端点 $in [l,r]$ 的区间的最大异或值,这个东西可以用可持久化 $Trie$ 来维护

    一开始把所有 $(i,i,n)$ 扔到堆里,然后每次取出计算贡献,设取得最大异或值的位置为 $t$,然后再把 $(o,l,t-1)$ 和 $(o,t+1,r)$ 扔到堆里

    具体还是看代码,很容易理解

    注意可能爆 $int$,所以要开 $unsigned int$,要注意代码常数

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    using namespace std;
    typedef long long ll;
    typedef unsigned int uint;
    inline uint read()
    {
        uint x=0; char ch=getchar();
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x;
    }
    const int N=1e6+7,M=1e7+7e6;
    uint n,K,sum[N],rt[N],t[M],pos[M],c[M][2];
    namespace Trie {
        uint cnt=0;
        void ins(uint &o,int p,uint pre,uint v,uint ps)
        {
            o=++cnt; t[o]=t[pre]+1;
            if(p<0) { pos[o]=ps; return; }
            int d=(v>>p)&1; c[o][d^1]=c[pre][d^1];
            ins(c[o][d],p-1,c[pre][d],v,ps);
        }
        uint query(uint o,int p,uint pre,uint v)
        {
            if(p<0) return pos[o];
            int d=(v>>p)&1;
            if(t[c[o][d^1]]-t[c[pre][d^1]]>0) return query(c[o][d^1],p-1,c[pre][d^1],v);
            else return query(c[o][d],p-1,c[pre][d],v);
        }
    }
    struct dat {
        uint o,l,r,t;
        dat (uint o,uint l,uint r) : o(o),l(l),r(r),t(Trie::query(rt[r],31,rt[l-1],sum[o-1])) {}
        inline bool operator < (const dat &tmp) const {
            return (sum[t]^sum[o-1])<(sum[tmp.t]^sum[tmp.o-1]);
        }
    };
    priority_queue <dat> Q;
    ll ans;
    int main()
    {
        n=read(),K=read(); uint a;
        Trie::ins(rt[0],31,0,0,0);
        for(int i=1;i<=n;i++)
        {
            a=read(); sum[i]=sum[i-1]^a;
            Trie::ins(rt[i],31,rt[i-1],sum[i],i);
        }
        for(int i=1;i<=n;i++) Q.push(dat(i,i,n));
        while(K--)
        {
            dat T=Q.top(); ans+=(sum[T.t]^sum[T.o-1]); Q.pop();
            if(T.l<T.t) Q.push(dat(T.o,T.l,T.t-1));
            if(T.r>T.t) Q.push(dat(T.o,T.t+1,T.r));
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    No-3.算数运算符
    No-2.注释
    No-1.第一个 Python 程序
    mtcnn网络训练--------------->>>
    sudo vim ~/.condarc
    CVPR2021佳作 | One-Shot都嫌多,Zero-Shot实例样本分割
    查询--主机硬件结构类型
    人群计数:
    共享盘登录
    C++---->>YOLOv4-detect_demo.py参考
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/10682774.html
Copyright © 2020-2023  润新知