zoukankan      html  css  js  c++  java
  • BZOJ3689 异或之

    题目链接:戳我

    十二省联考day1t1的近似原题啊!!!
    就是维护一个可持久化01trie,(可持久化01trie当然可以维护区间第K大啦!)然后一个二元组,放到优先队列里面。
    先放入以每一个点为右端点的异或最小值,取出之后放次小值,再取出之后放次次小值.......

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define MAXN 500010
    using namespace std;
    int n,tot=1,K;
    int rt[MAXN],cnt[MAXN<<5],t[MAXN<<5][2];
    long long a[MAXN];
    struct Node
    {
        int pos,maomao;
        long long sum;
        friend bool operator < (Node x,Node y)
            {return x.sum>y.sum;}
        Node(int x,int y,long long z):pos(x),maomao(y),sum(z){};
    };
    priority_queue<Node>q;
    inline void insert(int &x,int f,long long sum,int k)
    {
        x=++tot;
        cnt[x]=cnt[f]+1;
        t[x][0]=t[f][0],t[x][1]=t[f][1];
        if(k<0) return;
        int cur=((sum>>k)&1);
        if(!cur) 
            insert(t[x][0],t[f][0],sum,k-1);
        else 
            insert(t[x][1],t[f][1],sum,k-1);
    }
    inline long long query(int x,long long sum,int k)
    {
        // printf("x=%d sum=%lld k=%d
    ",x,sum,k);
        long long cur_ans=0;
        for(int i=31;i>=0;i--)
        {
            int cur=(sum>>i)&1;
            if(!cur)
            {
                if(k<=cnt[t[x][0]]) x=t[x][0],cur_ans=(cur_ans<<1);
                else k-=cnt[t[x][0]],x=t[x][1],cur_ans=(cur_ans<<1)|1;
            }
            else 
            {
                if(k<=cnt[t[x][1]]) x=t[x][1],cur_ans=(cur_ans<<1);
                else k-=cnt[t[x][1]],x=t[x][0],cur_ans=(cur_ans<<1)|1;
            }
        }
        return cur_ans;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        freopen("ce.out","w",stdout);
        #endif
        scanf("%d%d",&n,&K);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        rt[0]=1;
        for(int i=1;i<=n;i++) insert(rt[i],rt[i-1],a[i],31);
        // for(int i=1;i<=n;i++) printf("rt[%d]=%d
    ",i,rt[i]);
        for(int i=2;i<=n;i++)
        {
            long long cur_ans=query(rt[i-1],a[i],1);
            // printf("i=%d sum=%lld cur_ans=%lld
    ",i,a[i],cur_ans);
            q.push((Node){i,1,cur_ans});
        }
        for(int primy=1;primy<=K;primy++)
        {
            Node u=q.top();q.pop();
            printf("%lld ",u.sum);
            u.maomao++;
            if(u.maomao>u.pos-1) continue;
            long long cur_ans=query(rt[u.pos-1],a[u.pos],u.maomao);
            // printf("pos=%d sum=%lld cur_ans=%lld
    ",u.pos,a[u.pos],cur_ans);
            u.sum=cur_ans;
            q.push(u);
            // cout<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    设计模式(五)——单例模式
    设计模式(四)——工厂模式
    设计模式(三)—— 装饰者模式
    设计模式(二)—— 观察者模式
    JAVA环境配置
    在线求中位数
    不能对自己期望太大,但总是要拼一拼
    Leetcode | String to Integer (atoi)
    Leetcode | Simplify Path
    Leetcode | Longest Common Prefix
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10765350.html
Copyright © 2011-2022 走看看