zoukankan      html  css  js  c++  java
  • 【Luogu】P3567Kur-Couriers(主席树)

      题目链接

      数组大小开到一千二百万才过- -

      可以把数先离散化再全都加到主席树中。

      对于一个区间[from,to]

      取中间点mid

      看看小于mid的数有多少个,如果个数的两倍<=to-from+1那么左边就不存在我们要找的数。

      右面同理。如果大于mid的数<=to-from+1那么右面也不存在我们要找的数。

      如果两边都不存在就return 0;

      

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cstdlib>
    #include<algorithm>
    #define mid ((l+r)>>1)
    using namespace std;
    
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    long long rt[12000000];
    long long ls[12000000];
    long long rs[12000000];
    long long sum[12000000];
    long long q[1000000];
    long long s[1000000];
    int tot;
    
    void build(long long &o,int l,int r){
        o=++tot;    sum[o]=0;
        if(l==r)    return;
        build(ls[o],l,mid);
        build(rs[o],mid+1,r);
    }
    
    void update(long long &o,int l,int r,long long last,long long p){
        o=++tot; 
        ls[o]=ls[last];    rs[o]=rs[last];    sum[o]=sum[last]+1;
        if(l==r)    return;
        if(p<=mid)    update(ls[o],l,mid,ls[last],p);
        else        update(rs[o],mid+1,r,rs[last],p);
    }
    
    int query(int from,int to,int l,int r,int p){
        if(l==r)    return l;
        if(2*(sum[ls[to]]-sum[ls[from]])>p)    return query(ls[from],ls[to],l,mid,p);
        if(2*(sum[rs[to]]-sum[rs[from]])>p)    return query(rs[from],rs[to],mid+1,r,p);
        return 0;
    }
    
    int main(){
        int n=read(),m=read();
        for(int i=1;i<=n;++i)    s[i]=q[i]=read();
        sort(s+1,s+n+1);
        int size=unique(s+1,s+n+1)-(s+1);
        build(rt[0],1,size);
        for(int i=1;i<=n;++i)    q[i]=lower_bound(s+1,s+size+1,q[i])-s;
        for(int i=1;i<=n;++i)    update(rt[i],1,size,rt[i-1],q[i]);
        for(int i=1;i<=m;++i){
            int from=read(),to=read();
            printf("%lld
    ",s[query(rt[from-1],rt[to],1,size,to-from+1)]);
        }
        return 0;
    }
  • 相关阅读:
    js炫酷效果
    程序员的执着
    [心得]docker学习笔记
    [心得笔记]多线程之间的内存可见性问题
    Docker入门
    [心得体会]jvm
    redis学习总结
    [心得]redis集群环境搭建的错误
    Linux安装mysql5.7版本
    Cent OS下安装JDK11
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8078464.html
Copyright © 2011-2022 走看看