zoukankan      html  css  js  c++  java
  • BZOJ3110: [Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 11124  Solved: 3341
    [Submit][Status][Discuss]

    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

    题解:权值线段树+区间线段树 巩固永久标记优化空间(仍然没有处理好从下到上区间的更新  需要巩固)

    贴代码

    #include <bits/stdc++.h>
    #define ll long long
    const int MAXN=5e4+10;
    using namespace std;
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    int n,m,sz;
    vector<ll>vec;
    typedef struct que{
        int op,l,r;ll c;
    }que;
    que q[MAXN];
    int a,b,cnt;
    int rt[MAXN<<2];
    typedef struct node{
        ll flag,sum;int l,r;
    }node;
    node d[MAXN*16*16];
    void merge(int &x,int l,int r){
        if(!x)x=++cnt;
        if(a<=l&&r<=b){d[x].flag++;d[x].sum+=1ll*(r-l+1);return ;}
        int mid=(l+r)>>1;
        if(a<=mid)merge(d[x].l,l,mid);
        if(b>mid)merge(d[x].r,mid+1,r);
        d[x].sum=d[d[x].l].sum+d[d[x].r].sum+d[x].flag*1ll*(r-l+1);
    }
    void update(int root,int l,int r,int t){
        merge(rt[root],1,n);
        if(l==r)return ;
        int mid=(l+r)>>1;
        if(t<=mid)update(root<<1,l,mid,t);
        else update(root<<1|1,mid+1,r,t);
    }
    int ans;ll num;
    void querty1(int x,int l,int r,ll t){
        if(!x){num+=1ll*t*(min(b,r)-max(a,l)+1);return ;}
        if(a<=l&&r<=b){num+=1ll*t*(r-l+1);num+=d[x].sum;return ;}
        int mid=(l+r)>>1;
        if(a<=mid)querty1(d[x].l,l,mid,t+d[x].flag);
        if(b>mid)querty1(d[x].r,mid+1,r,t+d[x].flag);
    }
    void querty(int root,int l,int r,ll c){
        if(l==r){ans=l;return ;}
        int mid=(l+r)>>1;
        num=0;querty1(rt[root<<1],1,n,0);
        if(c<=num)querty(root<<1,l,mid,c);
        else querty(root<<1|1,mid+1,r,c-num);
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=m;i++){
    	q[i].op=read();q[i].l=read();q[i].r=read();q[i].c=read();
    	if(q[i].op==1)vec.push_back(q[i].c);
        }
        sort(vec.begin(),vec.end());
        sz=unique(vec.begin(),vec.end())-vec.begin();
        for(int i=1;i<=m;i++)if(q[i].op==1)q[i].c=lower_bound(vec.begin(),vec.begin()+sz,q[i].c)-vec.begin()+1;
        for(int i=1;i<=m;i++){
    	if(q[i].op==1){a=q[i].l,b=q[i].r;update(1,1,sz,q[i].c);}
    	else{
    	    a=q[i].l,b=q[i].r;
    	    num=0;querty1(rt[1],1,n,0);
    	    querty(1,1,sz,num-q[i].c+1);
    	    printf("%lld
    ",vec[ans-1]);
    	}
        }
        return 0;
    }
    
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    ddd
  • 原文地址:https://www.cnblogs.com/wang9897/p/9136856.html
Copyright © 2011-2022 走看看