zoukankan      html  css  js  c++  java
  • POJ 2104:K-th Number 整体二分

    感觉整体二分是个很有趣的东西。

    在别人的博客上看到一句话

    对于二分能够解决的询问,如果有多个,那么如果支持离线处理的话,那么就可以使用整体二分了

    树套树写了一天还是WA着,调得焦头烂额,所以决定学cdq分治的写法,虽然不知道整体二分和cdq有什么不可不说的关系,就先写了这道主席树模板题(orz LLZ大佬)。

    然后历史总是惊人的相似,和上午写cdq分治一样,又在同一个地方栽了跟头

    两个cdq模板都是cmp写错,两个整体二分都是把que[i]写成了i QAQ

    然后这个代码在洛谷上会T掉,在POJ可以A,就很难受了(vjudge上waiting了35分钟。。。)

    //Twenty
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    const int maxn=100000+100000+299;
    const int INF=1e9+7;
    int n,m,tot,sum[maxn],ans[maxn]; 
    struct node{
        int op,id,l,r,v;
        node(){};
        node(int op,int id,int l,int r,int v):op(op),id(id),l(l),r(r),v(v){}
    }p[maxn],tp[maxn];
    void input() {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) {
            int x;
            scanf("%d",&x);
            p[i]=node(1,i,i,i,x);
        }
        for(int i=1;i<=m;i++) {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            p[i+n]=node(0,i,x,y,z);
        }
    }
    void add(int x,int y) {
        for(;x<=n+m;x+=(x&(-x))) 
            sum[x]+=y;
    }
    int qry(int x) {
        int res=0;
        for(;x;x-=(x&(-x)))
            res+=sum[x];
        return res;   
    }
    #define mid ((l+r)>>1)
    int lq[maxn],rq[maxn];
    void solve(int ql,int qr,int l,int r) {
        if(l==5&&r==6) {
           int debug=1;
        }
        //int mid=((l+r)>>1);
        if(r<l||qr<ql) return;
        if(l==r) {
            for(int i=ql;i<=qr;i++) 
                if(p[i].op==0)
                    ans[p[i].id]=l;
            return;
        }
        int lcnt=0,rcnt=0;
        for(int i=ql;i<=qr;i++) {
            if(p[i].op) {   //insert
                if(p[i].v<=mid) {
                    add(p[i].id,1);
                    lq[++lcnt]=i;
                }
                else rq[++rcnt]=i;
            }
            else {  //query
                int now=qry(p[i].r)-qry(p[i].l-1);
                if(now>=p[i].v) lq[++lcnt]=i;
                else p[i].v-=now,rq[++rcnt]=i; 
            }
        }
        for(int i=1;i<=lcnt;i++) 
            if(p[lq[i]].op&&p[lq[i]].v<=mid) add(p[lq[i]].id,-1); 
        for(int i=0;i<lcnt;i++) tp[ql+i]=p[lq[i+1]];
        for(int i=0;i<rcnt;i++) tp[ql+lcnt+i]=p[rq[i+1]];
        for(int i=ql;i<=qr;i++) p[i]=tp[i];
        solve(ql,ql+lcnt-1,l,mid); 
        solve(ql+lcnt,qr,mid+1,r);
    }
    void print() {
        for(int i=1;i<=m;i++)
            printf("%d
    ",ans[i]);
    }
    int main()
    {
        input();
        solve(1,m+n,-INF,INF);
        print();
        return 0;
    }
    K-th number
  • 相关阅读:
    wait与sleep区别?
    oracle死锁查询
    atomic 原子操作的类
    买票问题
    0001.第一个多线程demo--分批处理数据
    01: JavaScript实例
    01: 运维工作梳理
    04: 使用BeautifulSoup封装的xss过滤模块
    04: 打开tornado源码剖析处理过程
    03: 自定义异步非阻塞tornado框架
  • 原文地址:https://www.cnblogs.com/Achenchen/p/7478806.html
Copyright © 2011-2022 走看看