zoukankan      html  css  js  c++  java
  • 整体二分(模板) 求区间第k小

    整体二分,将询问与初值一起放入一个结构体里,然后每次二分判断询问在哪边,树状数组维护,时间复杂度O((n+Q)lognlogMAX_a[i]

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    const int MAXN = 200005;
    const int inf = 1e9+1;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=ch=='-'?-1:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    struct Data{
        int x,y,k,id,type;
    }data[MAXN<<1],q1[MAXN<<1],q2[MAXN<<1];
    
    int n,m,cnt;
    int ans[MAXN],f[MAXN];
    
    inline void update(int x,int w){
        for(;x<=n;x+=x&-x) f[x]+=w;
    }
    
    inline int query(int x){
        int ret=0;
        for(;x;x-=x&-x) ret+=f[x];
        return ret;
    }
    
    void Solve(int ql,int qr,int l,int r){
        if(ql>qr) return;
        if(l==r){
            for(register int i=ql;i<=qr;i++)
                if(data[i].type==2) ans[data[i].id]=l;
            return;
        } 
        int mid=l+r>>1,p1=0,p2=0;
        for(register int i=ql;i<=qr;i++){
            if(data[i].type==1){
                if(data[i].x<=mid) {
                    q1[++p1]=data[i];
                    update(data[i].id,1);
                }else q2[++p2]=data[i];
            }
            else {
                int res=query(data[i].y)-query(data[i].x-1);
                if(res>=data[i].k) q1[++p1]=data[i];
                else{
                    data[i].k-=res;
                    q2[++p2]=data[i];
                }
            }
        }
        for(register int i=1;i<=p1;i++)
            if(q1[i].type==1) update(q1[i].id,-1);
        for(register int i=1;i<=p1;i++) data[i+ql-1]=q1[i];
        for(register int i=1;i<=p2;i++) data[i+ql+p1-1]=q2[i];
        Solve(ql,ql+p1-1,l,mid);Solve(ql+p1,qr,mid+1,r);
    }
    
    int main(){
        n=rd();m=rd();
        for(register int i=1;i<=n;i++) data[++cnt]=Data{rd(),1,inf,i,1};
        for(register int i=1;i<=m;i++) data[++cnt]=Data{rd(),rd(),rd(),i,2};
        Solve(1,cnt,-inf,inf);
        for(register int i=1;i<=m;i++) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    DWR3.0 如何应用的简单介绍(有实例)
    细线表格样式
    myeclipse不编译解决方法
    DORADO中resoler&dataProvider的常用方法
    jBPM插件下载地址及jBPM配置视频
    dorado要点总结
    千万级数据库(MSSQL)删除重复记录
    Dorado 7 IDE下载地址
    WIN CE和电脑之间的文件拷贝(2) Form1.cs文件
    获取所有存储过程源码替换存储过程方法
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676888.html
Copyright © 2011-2022 走看看