zoukankan      html  css  js  c++  java
  • Cogs 1345. [ZJOI2013] K大数查询(树套树)

    1. [ZJOI2013] K大数查询
      这里写图片描述
    /*
    树套树写法.
    bzoj过不了.
    可能有负数要离散吧.
    线段树套线段树.
    外层权值线段树,内层区间线段树维护标记.
    对权值建一棵权值线段树.
    某个点表示权值在某个范围内的数的个数.
    然后对每个点建一棵区间线段树.
    表示该权值范围在某个区间的数的个数.
    然后查找用类似二分的思想.
    */
    #include<iostream>
    #include<cstdio>
    #define MAXN 50001
    using namespace std;
    struct data{int lc,rc,sum,size,bj;}tree[MAXN*400];
    int n,m,root[MAXN],cut;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void push(int k,int l,int r)
    {
        if(!tree[k].lc) tree[k].lc=++cut;
        if(!tree[k].rc) tree[k].rc=++cut;
        tree[tree[k].lc].bj+=tree[k].bj;
        tree[tree[k].rc].bj+=tree[k].bj;
        int mid=(l+r)>>1;
        tree[tree[k].lc].sum+=(mid-l+1)*tree[k].bj;
        tree[tree[k].rc].sum+=(r-mid)*tree[k].bj;
        tree[k].bj=0;
        return ;
    }
    void add(int &k,int l,int r,int x,int y)
    {
        if(!k) k=++cut;
        if(x==l&&r==y)
        {
            tree[k].bj++;
            tree[k].sum+=r-l+1;
            return ;
        }
        if(tree[k].bj) push(k,l,r);
        int mid=(l+r)>>1;
        if(y<=mid) add(tree[k].lc,l,mid,x,y);
        else if(x>mid) add(tree[k].rc,mid+1,r,x,y);
        else add(tree[k].lc,l,mid,x,mid),add(tree[k].rc,mid+1,r,mid+1,y);
        tree[k].sum=tree[tree[k].lc].sum+tree[tree[k].rc].sum;
        return ;
    }
    void sloveadd(int x,int y,int z)
    //先找到它所在权值的位置然后在[x,y]处加入贡献.
    {
        int l=1,r=n,k=1,mid;
        while(l!=r)
        {
            mid=(l+r)>>1;
            add(root[k],1,n,x,y);
            if(z<=mid) r=mid,k=k<<1;
            else l=mid+1,k=(k<<1)+1;
        }
        add(root[k],1,n,x,y);
        return ;
    }
    int query(int k,int l,int r,int x,int y)
    {
        if(!k) return 0;
        if(tree[k].bj) push(k,l,r);
        if(x<=l&&r<=y) return tree[k].sum;
        int tot=0,mid=(l+r)>>1;
        if(x<=mid) tot+=query(tree[k].lc,l,mid,x,y);
        if(y>mid) tot+=query(tree[k].rc,mid+1,r,x,y);
        return tot;
    }
    int slovequery(int x,int y,int z)
    {
        int l=1,r=n,k=1;
        while(l!=r)
        {
            int mid=(l+r)>>1;
            int t=query(root[k<<1],1,n,x,y);
            if(t>=z) r=mid,k<<=1;
            else l=mid+1,k=(k<<1)+1,z-=t;
        }
        return l;
    }
    int main()
    {
        freopen("zjoi13_sequence.in","r",stdin);
        freopen("zjoi13_sequence.out","w",stdout);
        int k,x,y,z;
        n=read(),m=read();
        while(m--)
        {
            k=read(),x=read(),y=read(),z=read();
            if(k&1) sloveadd(x,y,n-z+1);
            else printf("%d
    ",n-slovequery(x,y,z)+1);
        }
        return 0;
    }
  • 相关阅读:
    Java泛型-类型擦除
    static加载问题
    当使用System,out.println()打印一个对象是自动调用toString方法
    python——变量作用域及嵌套作用域
    Python 构造函数、 Python 析构函数、Python 垃圾回收机制
    python——type()创建类
    HTML4,HTML5,XHTML 之间有什么区别?
    斐波那契数列算法分析
    python——iterator迭代器|iterator详解——20140918|
    django model filter 条件过滤,及多表连接查询、反向查询,某字段的distinct
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068103.html
Copyright © 2011-2022 走看看