• 【bzoj3110】[Zjoi2013]K大数查询


    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操作中abs(c)<=Maxlongint

    一直不是很理解树套树是个什么鬼。
    题解告诉我此题为线段树套线段树。一维维护权值,二维维护区间。
    精髓还没有领悟到,果真我还是很弱QWQ
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #include<cstring>
     6 #define ll long long 
     7 using namespace std;
     8 int a,b,c;
     9 int n,m,sz;
    10 int root[200005];
    11 int ls[20000005],rs[20000005],sum[20000005],lazy[20000005];
    12 void pushdown(int k,int l,int r){
    13     if ((!lazy[k])||l==r) return;//如果没标记或者已经到了底层
    14     if (!ls[k])ls[k]=++sz;
    15     if (!rs[k])rs[k]=++sz;
    16     int mid=(l+r)>>1;
    17     lazy[ls[k]]+=lazy[k];lazy[rs[k]]+=lazy[k];
    18     sum[ls[k]]+=(mid-l+1)*lazy[k];
    19     sum[rs[k]]+=(r-mid)*lazy[k];
    20     lazy[k]=0;
    21 }
    22 
    23 void modify(int &k,int l,int r,int a,int b){
    24     if (!k)k=++sz;
    25     pushdown(k,l,r);
    26     if (a==l&&b==r){
    27         lazy[k]++;
    28         sum[k]+=(r-l+1);
    29         return;
    30     }
    31     int mid=(l+r)>>1;
    32     if (a>mid) modify(rs[k],mid+1,r,a,b);
    33     else if (b<=mid) modify(ls[k],l,mid,a,b);
    34     else modify(ls[k],l,mid,a,mid),modify(rs[k],mid+1,r,mid+1,b); 
    35     sum[k]=sum[ls[k]]+sum[rs[k]];
    36 }
    37 
    38 void insert(){
    39     int l=1,r=n,k=1;
    40     while (l!=r){
    41         modify(root[k],1,n,a,b);
    42         int mid=(l+r)>>1;
    43         if (c>mid)l=mid+1,k=k<<1|1;
    44         else r=mid,k=k<<1;
    45     }
    46     modify(root[k],1,n,a,b);
    47 }
    48 
    49 int query(int k,int l,int r,int a,int b){
    50     if (!k) return 0;
    51     pushdown(k,l,r);
    52     if (a==l&&b==r)return sum[k];
    53     int mid=(l+r)>>1;
    54     if (a>mid) return query(rs[k],mid+1,r,a,b);
    55     else if (b<=mid) return query(ls[k],l,mid,a,b);
    56     else return query(ls[k],l,mid,a,mid)+query(rs[k],mid+1,r,mid+1,b);
    57 }
    58 
    59 int solve(){
    60     int l=1,r=n,k=1;
    61     while (l!=r){
    62         int t=query(root[k<<1],1,n,a,b);
    63         int mid=(l+r)>>1;
    64         if (t>=c)r=mid,k=k<<1;
    65         else l=mid+1,k=k<<1|1,c-=t;
    66     }
    67     return l;
    68 }
    69 
    70 int main(){
    71     freopen("sj.txt","r",stdin);
    72     freopen("me.txt","w",stdout);
    73     scanf("%d%d",&n,&m);
    74     for (int i=1;i<=m;i++){
    75         int f;
    76         scanf("%d%d%d%d",&f,&a,&b,&c);
    77         if (f==1)c=n-c+1,insert();
    78         else printf("%d
    ",n-solve()+1);
    79     }
    80 }
  • 相关阅读:
    启动dubbo服务时报 qosserver can not bind localhost:22222 异常处理
    PostSharp学习
    为什么需要经验丰富的程序员
    商品入库及加入购物车简易流程
    python 中enumerate函数(千年虫)
    将两个列表转成集合(星座性格特点匹配)
    nginx入门手册
    迟来的2021总结
    selenium chrome正在受到自动测试软件的控制
    selenium 上传文件
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5149672.html
Copyright © 2020-2023  润新知