码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-12-10 13:15:12      阅读:95      评论:0      收藏:0      [点我收藏+]

标签:++   void   namespace   cer   end   problem   register   struct   har   

题意

类似超级钢琴,找最优解用可持久化trie。

code:

#include<bits/stdc++.h>
using namespace std;
#define re register
typedef long long ll;
const int maxn=5*1e5+10;
int n,m,tot;
int root[maxn],last[maxn*40*2];
int trie[maxn*40][2];
ll ans;
ll a[maxn],sum[maxn];
struct node
{
    int x,l,r,t;ll val;
    bool operator<(const node& a)const{return val<a.val;}
};
priority_queue<node>q;
inline ll read()
{
    char c=getchar();ll res=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
    return res*f;
}
void insert(int pre,int now,int t,ll k,int id)
{
    if(t<0){last[now]=id;return;}
    int c=(k>>t)&1;
    if(pre)trie[now][c^1]=trie[pre][c^1];
    trie[now][c]=++tot;
    insert(trie[pre][c],trie[now][c],t-1,k,id);
    last[now]=max(last[trie[now][0]],last[trie[now][1]]);
}
int query(int now,int t,ll k,int lim)
{
    if(t<0)return last[now];
    int c=(k>>t)&1;
    if(last[trie[now][c^1]]>=lim)return query(trie[now][c^1],t-1,k,lim);
    else return query(trie[now][c],t-1,k,lim);
}
int main()
{
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
    n=read(),m=read();
    for(re int i=1;i<=n;i++)a[i]=read(),sum[i]=sum[i-1]^a[i];
    root[0]=++tot;last[0]=-1;insert(0,root[0],35,0,0);
    for(re int i=1;i<=n;i++)root[i]=++tot,insert(root[i-1],root[i],35,sum[i],i);
    for(re int i=1;i<=n;i++)
    {
        int pos=query(root[n],35,sum[i-1],i);
        //cerr<<(sum[pos]^sum[i-1])<<endl;
        q.push((node){i,i,n,pos,sum[pos]^sum[i-1]});
    }
    while(m--)
    {
        node now=q.top();q.pop();
        ans+=now.val;
        if(now.t>now.l)
        {
            int pos=query(root[now.t-1],35,sum[now.x-1],now.l);
            q.push((node){now.x,now.l,now.t-1,pos,sum[now.x-1]^sum[pos]});
        }
        if(now.t<now.r)
        {
            int pos=query(root[now.r],35,sum[now.x-1],now.t+1);
            q.push((node){now.x,now.t+1,now.r,pos,sum[now.x-1]^sum[pos]});      
        }
    }
    printf("%lld",ans);
    return 0;
}

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

标签:++   void   namespace   cer   end   problem   register   struct   har   

原文地址:https://www.cnblogs.com/nofind/p/12015694.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!