• bzoj 3110 K大数查询


         第一道整体二分,因为只需要知道每个询问区间中比mid大的数有多少个,就可以直接用线段树区间加,区间求和了。

        

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define int long long
      6 #define N 50005
      7 #define ls x*2,l,mid
      8 #define rs x*2+1,mid+1,r
      9 using namespace std;
     10 int n,m;
     11 struct node
     12 {
     13     int sign,x,y,c;
     14 }op[N];
     15 int q[N],ans[N];
     16 int a[N*8],lazy[N*8];
     17 void push_down(int x,int l,int mid,int r)
     18 {
     19     if(lazy[x]!=0)
     20     {
     21         lazy[x*2]+=lazy[x];
     22         lazy[x*2+1]+=lazy[x];
     23         a[x*2]+=lazy[x]*(mid-l+1);
     24         a[x*2+1]+=lazy[x]*(r-mid);
     25         lazy[x]=0;
     26     }
     27     return ;
     28 }
     29 int qur(int x,int l,int r,int ll,int rr)
     30 {
     31     if(l>=ll&&r<=rr)return a[x];
     32     int mid=(l+r)>>1;
     33     push_down(x,l,mid,r);
     34     if(rr<=mid)return qur(ls,ll,rr);
     35     if(ll>mid)return qur(rs,ll,rr);
     36     return qur(ls,ll,rr)+qur(rs,ll,rr);
     37 }
     38 void gai(int x,int l,int r,int ll,int rr,int d)
     39 {
     40     if(l>=ll&&r<=rr)
     41     {
     42         lazy[x]+=d;
     43         a[x]+=d*(r-l+1);
     44         return ;
     45     }
     46     int mid=(l+r)>>1;
     47     push_down(x,l,mid,r);
     48     if(ll<=mid)gai(ls,ll,rr,d);
     49     if(rr>mid)gai(rs,ll,rr,d);
     50     a[x]=a[x*2]+a[x*2+1];
     51 }
     52 int tmp[2][N];
     53 void solve(int L,int R,int l,int r)
     54 {
     55     if(L>R)return ;
     56     if(l==r)
     57     {
     58         for(int i=L;i<=R;i++)if(op[q[i]].sign==2)ans[q[i]]=l;
     59         return ;
     60     }
     61     int mid=(l+r)>>1;
     62     int cnt1=0,cnt2=0;
     63     for(int i=L;i<=R;i++)
     64     {
     65         if(op[q[i]].sign==1)
     66         {
     67             if(op[q[i]].c>mid)
     68             {
     69                 gai(1,1,n,op[q[i]].x,op[q[i]].y,1);
     70                 tmp[1][++cnt2]=q[i];
     71             }            
     72             else tmp[0][++cnt1]=q[i];
     73         }
     74         else
     75         {
     76             int y=qur(1,1,n,op[q[i]].x,op[q[i]].y);
     77             if(y>=op[q[i]].c)
     78             {
     79                 tmp[1][++cnt2]=q[i];
     80             }
     81             else op[q[i]].c-=y,tmp[0][++cnt1]=q[i];
     82         }
     83     }
     84     for(int i=L;i<=R;i++)
     85     {
     86         if(op[q[i]].sign==1)
     87         {
     88             if(op[q[i]].c>mid)gai(1,1,n,op[q[i]].x,op[q[i]].y,-1);        
     89         }
     90     }
     91     int l1=L+cnt1-1;
     92     for(int i=1;i<=cnt1;i++)q[L+i-1]=tmp[0][i];
     93     for(int i=1;i<=cnt2;i++)q[l1+i]=tmp[1][i];
     94     solve(L,l1,l,mid);solve(l1+1,R,mid+1,r);
     95 }
     96 signed main()
     97 {
     98     scanf("%lld%lld",&n,&m);
     99     for(int i=1;i<=m;i++)
    100     {
    101         scanf("%lld%lld%lld%lld",&op[i].sign,&op[i].x,&op[i].y,&op[i].c);
    102         q[i]=i;
    103     }
    104     solve(1,m,1,n);
    105     for(int i=1;i<=m;i++)
    106     {
    107         if(op[i].sign==2)printf("%lld
    ",ans[i]);
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    springboot 2.4.5 redis 配置类+缓存
    华为ensp模拟器 提示40 错误问题
    Nodejs
    Python PermissionError:[Errno 13]权限被拒绝 [winerr 5]
    Window10的linux docker 安装(wsl版本)
    window10的 Linux 子系统ssh配置
    vue3.0中provide和inject实现响应式传值
    正确开启vue3.0调试工具vue-devtools
    vue动态设置组件样式
    element-ui菜单导航的三种递归写法(三)
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6155920.html
Copyright © 2020-2023  润新知