zoukankan      html  css  js  c++  java
  • bzoj 5495: [2019省队联测]异或粽子【可持久化trie+大根堆】

    和bzoj4504差不多,就是换了个数据结构
    像超级钢琴一样把五元组放进大根堆,每次取一个出来拆开,(d,l,r,p,v)表示右端点为d,左端点区间为(l,r),最大区间和值为v左端点在p上
    关于怎么快速求区间和,用一个可持久trie上维护最大xor值和对应的点即可

    #include<iostream>
    #include<cstdio>
    #include<queue>
    //#include<ctime>
    using namespace std;
    const int N=500005;
    int n,m,rt[N],tot;
    unsigned int a[N],s[N],b[35];
    long long ans;
    struct trie
    {
        int c[2],s,p;
    }t[20000005];
    struct qwe
    {
        int d,l,r,p;
        unsigned int v;
        qwe(int D=0,int L=0,int R=0,int P=0,unsigned int V=0)
        {
            d=D,l=L,r=R,p=P,v=V;
        }
        bool operator < (const qwe &a) const
        {
            return v<a.v;
        }
    };
    priority_queue<qwe>q;
    long long read()
    {
        long long r=0,f=1;
        char p=getchar();
        while(p>'9'||p<'0')
        {
            if(p=='-')
                f=-1;
            p=getchar();
        }
        while(p>='0'&&p<='9')
        {
            r=r*10+p-48;
            p=getchar();
        }
        return r*f;
    }
    void ins(int &ro,int la,int w,int id)
    {
        ro=++tot;
        t[ro]=t[la];
        t[ro].s++;
        if(w==-1)
        {
            t[ro].p=id;
            return;
        }
        bool p=(s[id]&b[w]);//cerr<<w<<" "<<p<<endl;
        ins(t[ro].c[p],t[la].c[p],w-1,id);
    }
    pair<int,unsigned int>ques(int la,int ro,int id,int w,unsigned int v)
    {//cerr<<t[ro].s-t[la].s<<endl;
        if(w==-1)
            return make_pair(t[ro].p,v);
        bool p=(s[id]&b[w]);//cerr<<w<<" "<<p<<" "<<t[t[ro].c[p^1]].s<<" "<<t[t[la].c[p^1]].s<<endl;
        if(t[t[ro].c[p^1]].s-t[t[la].c[p^1]].s>0)
            return ques(t[la].c[p^1],t[ro].c[p^1],id,w-1,v|b[w]);
        else
            return ques(t[la].c[p],t[ro].c[p],id,w-1,v);
    }
    int main()
    {
        // freopen("xor.in","r",stdin);
        // freopen("xor.out","w",stdout);
        n=read(),m=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        b[0]=1;
        for(int i=1;i<=31;i++)
            b[i]=(b[i-1]<<1);
        for(int i=n;i>=1;i--)
            s[i]=s[i+1]^a[i];
        rt[0]=++tot;
        for(int i=1;i<=n;i++)
            ins(rt[i],rt[i-1],31,i);//cerr<<"OK"<<endl;
        for(int i=1;i<=n;i++)
        {
            pair<int,unsigned int>nw=ques(rt[0],rt[i],i+1,31,0);
            q.push(qwe(i,1,i,nw.first,nw.second));
        }
        while(m--)
        {
            qwe u=q.top();//cerr<<u.v<<endl;
            q.pop();
            ans+=u.v;
            if(u.l<=u.p-1)
            {
                pair<int,unsigned int>nw=ques(rt[u.l-1],rt[u.p-1],u.d+1,31,0);
                q.push(qwe(u.d,u.l,u.p-1,nw.first,nw.second));
            }
            if(u.p+1<=u.r)
            {
                pair<int,unsigned int>nw=ques(rt[u.p],rt[u.r],u.d+1,31,0);
                q.push(qwe(u.d,u.p+1,u.r,nw.first,nw.second));
            }
        }//cerr<<clock()<<endl;
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    皮皮书屋要关掉了
    Java容器类接口:Iterator,Collection,Map
    Java容器类概述
    Linux Mint下安装JDK
    [zz]论程序员
    Java私有构造器
    List of Free Programming Books
    5种你未必知道的JavaScript和CSS交互的方法
    【HTTP】GET和POST的区别
    ASP.NET转换人民币大小金额
  • 原文地址:https://www.cnblogs.com/lokiii/p/10712165.html
Copyright © 2011-2022 走看看