• BZOJ


    题目链接

    权值线段树套区间线段树,权值线段树的每个结点存储该结点所表示的区间范围内的数在各个区间的分布情况,查询时在权值线段树上二分即可。复杂度$O(nlog^2n)$

    注意区间线段树需要动态开点,并且标记要永久化,否则会TLE。

    另外就是sum可能会爆int,需要用long long存储。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef double db;
     5 const int N=5e4+10;
     6 #define lson (u<<1)
     7 #define rson (u<<1|1)
     8 #define mid ((l+r)>>1)
     9 int n,m,rt[N<<2],ls[N*200],rs[N*200],tot;
    10 ll mk[N*200],sum[N*200];
    11 int newnode() {int u=++tot; ls[u]=rs[u]=sum[u]=0; return u;}
    12 void upd2(int L,int R,int x,int& u,int l=1,int r=n) {
    13     if(!u)u=newnode();
    14     if(l>=L&&r<=R) {sum[u]+=(r-l+1)*x; mk[u]+=x; return;}
    15     if(l>R||r<L)return;
    16     upd2(L,R,x,ls[u],l,mid),upd2(L,R,x,rs[u],mid+1,r);
    17     sum[u]+=(ll)(min(r,R)-max(l,L)+1)*x;
    18 }
    19 ll qry2(int L,int R,int& u,int l=1,int r=n) {
    20     if(l>=L&&r<=R)return sum[u];
    21     if(l>R||r<L)return 0;
    22     return qry2(L,R,ls[u],l,mid)+qry2(L,R,rs[u],mid+1,r)+(ll)(min(r,R)-max(l,L)+1)*mk[u];
    23 }
    24 void upd(int p,int L,int R,int u=1,int l=1,int r=n) {
    25     upd2(L,R,1,rt[u]);
    26     if(l==r)return;
    27     p<=mid?upd(p,L,R,lson,l,mid):upd(p,L,R,rson,mid+1,r);
    28 }
    29 int qry(int L,int R,int k,int u=1,int l=1,int r=n) {
    30     if(l==r)return l;
    31     ll t=qry2(L,R,rt[rson]);
    32     return k<=t?qry(L,R,k,rson,mid+1,r):qry(L,R,k-t,lson,l,mid);
    33 }
    34 int main() {
    35     scanf("%d%d",&n,&m);
    36     while(m--) {
    37         int f,l,r,x;
    38         scanf("%d%d%d%d",&f,&l,&r,&x);
    39         if(f==1)upd(x,l,r);
    40         else printf("%d
    ",qry(l,r,x));
    41     }
    42     return 0;
    43 }
  • 相关阅读:
    迭代器、生成器、装饰器(转)
    Python小数据池
    接阿里云oss有感
    VSCode快捷键
    前端跨域调请求 nginx反向代理
    Git生成密钥
    【westorm系列之二】配置格式化
    钉钉安卓端无法渲染数据
    express 写接口
    js正则匹配身份证号 有坑
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10685630.html
Copyright © 2020-2023  润新知