• [BZOJ3110][Zjoi2013]K大数查询 树套树


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3110

    我们建一棵权值线段树,并对里面的节点建普通区间线段树,注意动态开点。对于查询就用类似于二分的操作就好了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 typedef unsigned int uint;
     6 int inline readint(){
     7     int Num=0,Flag=1;char ch;
     8     while((ch=getchar())<'0'||ch>'9') if(ch=='-') break;
     9     if(ch=='-') Flag=-1; else Num=ch-'0';
    10     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
    11     return Num*Flag;
    12 }
    13 void outint(int x){
    14     if(x>=10) outint(x/10);
    15     putchar(x%10+'0');
    16 }
    17 int n,m,opt,a,b,c;
    18 int rt[(50000<<2)+10],lc[20000000],rc[20000000],col[20000000],cnt=0;
    19 uint sum[20000000];
    20 void inline Pushup(int &x){
    21     sum[x]=sum[lc[x]]+sum[rc[x]];
    22 }
    23 void inline Pushdown(int &x,int l,int r){
    24     if(!col[x]||l==r) return;
    25     if(!lc[x]) lc[x]=++cnt;
    26     if(!rc[x]) rc[x]=++cnt;
    27     col[lc[x]]+=col[x];
    28     col[rc[x]]+=col[x];
    29     uint mid=l+r>>1;
    30     sum[lc[x]]+=(mid-l+1)*col[x];
    31     sum[rc[x]]+=(r-mid)*col[x];
    32     col[x]=0;
    33 }
    34 void Modify(int &x,int l,int r,int L,int R){
    35     if(!x) x=++cnt;
    36     if(L<=l&&r<=R){
    37         col[x]++;
    38         sum[x]+=r-l+1;
    39         return;
    40     }
    41     Pushdown(x,l,r);
    42     int mid=l+r>>1;
    43     if(L<=mid) Modify(lc[x],l,mid,L,R);
    44     if(R>mid) Modify(rc[x],mid+1,r,L,R);
    45     Pushup(x);
    46 }
    47 uint Qry(int &x,int l,int r,int L,int R){
    48     if(L<=l&&r<=R) return sum[x];
    49     Pushdown(x,l,r);
    50     int mid=l+r>>1;
    51     uint s=0;
    52     if(L<=mid) s=Qry(lc[x],l,mid,L,R);
    53     if(R>mid) s+=Qry(rc[x],mid+1,r,L,R);
    54     return s;
    55 }
    56 void Insert(){
    57     int x=1,l=1,r=n;
    58     while(l!=r){
    59         int mid=l+r>>1;
    60         Modify(rt[x],1,n,a,b);
    61         if(c<=mid) r=mid,x<<=1;
    62         else l=mid+1,x=x<<1|1;
    63     }
    64     Modify(rt[x],1,n,a,b);
    65 }
    66 void Solve(){
    67     int x=1,l=1,r=n;
    68     while(l!=r){
    69         int mid=l+r>>1;
    70         uint rk=Qry(rt[x<<1|1],1,n,a,b);
    71         if(rk>=c) l=mid+1,x=x<<1|1;
    72         else r=mid,x<<=1,c-=rk;
    73     }
    74     outint(l);
    75     putchar('
    ');
    76 }
    77 int main(){
    78     n=readint();
    79     m=readint();
    80     for(int i=1;i<=m;i++){
    81         opt=readint();
    82         a=readint();
    83         b=readint();
    84         c=readint();
    85         if(opt==1) Insert();
    86         else Solve();
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    except与besides
    think用法
    walk用法
    complain用法
    go through用法
    herd用法
    ridiculous用法
    it is the same as用法
    let us say用法
    1002 A+B for Polynomials (25 分)(模拟)
  • 原文地址:https://www.cnblogs.com/halfrot/p/7553980.html
Copyright © 2020-2023  润新知