zoukankan      html  css  js  c++  java
  • K大数查询

    3110: [Zjoi2013]K大数查询

    Time Limit: 20 Sec  Memory Limit: 512 MB

    Description

    有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
    如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。

    Input

    第一行N,M
    接下来M行,每行形如1 a b c或2 a b c

    Output

    输出每个询问的结果

    Sample Input

    2 5
    1 1 2 1
    1 1 2 2
    2 1 1 2
    2 1 1 1
    2 1 2 3

    Sample Output

    1
    2
    1

    HINT



    【样例说明】

    第一个操作 后位置 1 的数只有 1 , 位置 2 的数也只有 1 。 第二个操作 后位置 1

    的数有 1 、 2 ,位置 2 的数也有 1 、 2 。 第三次询问 位置 1 到位置 1 第 2 大的数 是

    1 。 第四次询问 位置 1 到位置 1 第 1 大的数是 2 。 第五次询问 位置 1 到位置 2 第 3

    大的数是 1 。‍


    N,M<=50000,N,M<=50000

    a<=b<=N

    1操作中abs(c)<=N

    2操作中c<=Maxlongint

     分析:区间线段树套权值线段树;

        修改时就把对应权值范围内的线段树区间修改;

        查询时二分查询即可;

        看博客发现lazy不pushdown直接永久化标记会更快,orz;

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <bitset>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #define rep(i,m,n) for(i=m;i<=n;i++)
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define sys system("pause")
    const int maxn=5e4+10;
    const int M=maxn*16*16;
    using namespace std;
    inline ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    inline ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
    inline int id(int l,int r){return l+r|l!=r;}
    inline void umax(ll &p,ll q){if(p<q)p=q;}
    inline void umin(ll &p,ll q){if(p>q)p=q;}
    inline ll read()
    {
        ll x=0;int 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-'0';ch=getchar();}
        return x*f;
    }
    int n,m,k,t,root[maxn*2],ls[M],rs[M],sz,num,L,R;
    ll sum[M],lazy[M],a[maxn];
    struct node
    {
        int a,b,c;
        ll d;
    }q[maxn];
    void push_down(int l,int r,int k)
    {
        int mid=l+r>>1;
        if(!ls[k])ls[k]=++sz;
        if(!rs[k])rs[k]=++sz;
        sum[ls[k]]+=lazy[k]*(mid-l+1);
        sum[rs[k]]+=lazy[k]*(r-mid);
        lazy[ls[k]]+=lazy[k],lazy[rs[k]]+=lazy[k];
        lazy[k]=0;
    }
    void push_up(int k){sum[k]=sum[ls[k]]+sum[rs[k]];}
    void insert(int L,int R,int l,int r,int&k)
    {
        if(!k)k=++sz;
        if(l==L&&r==R)
        {
            lazy[k]++;
            sum[k]+=r-l+1;
            return;
        }
        int mid=l+r>>1;
        if(lazy[k])push_down(l,r,k);
        if(R<=mid)insert(L,R,l,mid,ls[k]);
        else if(L>mid)insert(L,R,mid+1,r,rs[k]);
        else
        {
            insert(L,mid,l,mid,ls[k]);
            insert(mid+1,R,mid+1,r,rs[k]);
        }
        push_up(k);
    }
    ll cal(int L,int R,int l,int r,int k)
    {
        if(l==L&&r==R)return sum[k];
        int mid=l+r>>1;
        if(lazy[k])push_down(l,r,k);
        if(R<=mid)return cal(L,R,l,mid,ls[k]);
        else if(L>mid)return cal(L,R,mid+1,r,rs[k]);
        else return cal(L,mid,l,mid,ls[k])+cal(mid+1,R,mid+1,r,rs[k]);
    }
    void add(int L,int R,int l,int r,int x)
    {
        insert(L,R,1,n,root[id(l,r)]);
        if(l==r)return;
        int mid=l+r>>1;
        if(x<=mid)add(L,R,l,mid,x);
        else add(L,R,mid+1,r,x);
    }
    int gao(int L,int R,int l,int r,ll x)
    {
        if(l==r)return l;
        int mid=l+r>>1;
        ll tmp;
        tmp=cal(L,R,1,n,root[id(mid+1,r)]);
        if(tmp>=x)return gao(L,R,mid+1,r,x);
        else return gao(L,R,l,mid,x-tmp);
    }
    int main()
    {
        int i,j;
        scanf("%d%d",&n,&m);
        rep(i,1,m)
        {
            scanf("%d%d%d%lld",&q[i].a,&q[i].b,&q[i].c,&q[i].d);
            if(q[i].a==1)a[++num]=q[i].d;
        }
        sort(a+1,a+num+1);
        num=unique(a+1,a+num+1)-a-1;
        rep(i,1,m)
        {
            if(q[i].a==1)
            {
                q[i].d=lower_bound(a+1,a+num+1,q[i].d)-a;
                add(q[i].b,q[i].c,1,num,q[i].d);
            }
            else
            {
                printf("%lld
    ",a[gao(q[i].b,q[i].c,1,num,q[i].d)]);
            }
        }
        return 0;
    }
  • 相关阅读:
    [NOI2014]动物园
    [NOI2014]起床困难综合症
    bzoj2688 Green Hackenbush
    luogu P2575 高手过招
    [NOI2015]荷马史诗
    win10系统U盘读取不了怎么解决 三种方法快速解决&quot;文件或目录损坏且无法读取& 发布时间:2020-06-05 09:19:46 作者:佚名 我要评论
    在 Linux 中,最直观、最可见的部分就是 文件系统(file system)
    GB 18030-2000《信息技术信息交换用汉字编码字符集基本集的扩充
    docker 分层 隔离
    DNS和BIND
  • 原文地址:https://www.cnblogs.com/dyzll/p/6370636.html
Copyright © 2011-2022 走看看