#6278. 数列分块入门 2(询问区间内小于某个值 xx 的元素个数)

题目链接:https://loj.ac/problem/6278

题目大意:中文题目

具体思路:数列分块模板题,对于更新的时候,我们通过一个辅助数组来进行,对于原始的数组,我们只是用来加减,然后这个辅助数组的作用就是对每一块进行排序,当查询的时候,如果不是整块的,我们直接通过a数组来记录,对于整块的,我们直接通过排序的辅助数组进行二分查找就可以了。

注意每一次更新,除了整块的,我们都需要进行对b数组这一整块的重新赋值,因为只是部分赋值的话,b数组已经排序了,这样的话数组的下标对应的数就已经改变了。

lower_bound查询的时候, id=lower_bound(b+l[i],b+r[i]+1,tmp)-(b+l[i]);如果是需要记录小于的个数的话,直接减去b+l[i]就是个数了。

A代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 # define ll long long
  4 const int maxn =  2e5+100;
  5 const int mod = 1e8+7;
  6 ll l[maxn],r[maxn],belong[maxn];
  7 ll add[maxn],a[maxn],b[maxn];
  8 int n;
  9 void buildblock()
 10 {
 11     ll tmp=(ll)sqrt(n);
 12     ll tot=n/tmp;
 13     if(n%tmp)
 14         tot++;
 15     for(ll i=1; i<=n; i++)
 16     {
 17         belong[i]=(i-1)/tmp+1ll;
 18     }
 19     for(ll  i=1; i<=tot; i++)
 20     {
 21         l[i]=(i-1)*tmp+1ll;
 22         r[i]=i*tmp;
 23     }
 24     r[tot]=n;
 25     for(ll i=1; i<=tot; i++)
 26     {
 27         sort(b+l[i],b+r[i]+1);
 28     }
 29 }
 30 void init(int tmp){
 31     for(int i=l[tmp];i<=r[tmp];i++)b[i]=a[i];
 32     sort(b+l[tmp],b+r[tmp]+1);
 33 }
 34 void update(ll st,ll ed,ll val)
 35 {
 36     if(belong[st]==belong[ed])
 37     {
 38         for(ll i=st; i<=ed; i++)a[i]+=val;
 39         init(belong[st]);
 40         return ;
 41     }
 42     for(ll i=st; i<=r[belong[st]]; i++)a[i]+=val;
 43     init(belong[st]);
 44     for(ll  i=l[belong[ed]]; i<=ed; i++)a[i]+=val;
 45     init(belong[ed]);
 46     for(ll i=belong[st]+1; i<belong[ed]; i++)
 47         add[i]+=val;
 48 }
 49 ll ask(ll st,ll ed,ll val)
 50 {
 51     ll ans=0;
 52     if(belong[st]==belong[ed])
 53     {
 54         for(ll i=st; i<=ed; i++)
 55         {
 56             if(a[i]+add[belong[st]]<val)
 57                 ans++;
 58         }
 59         return ans;
 60     }
 61     for(ll i=st; i<=r[belong[st]]; i++)
 62     {
 63         ans+=(a[i]+add[belong[st]]<val?1:0);
 64     }
 65     for(ll i=l[belong[ed]]; i<=ed; i++)
 66     {
 67         ans+=(a[i]+add[belong[ed]]<val?1:0);
 68     }
 69     for(ll i=belong[st]+1; i<belong[ed]; i++)
 70     {
 71         ll tmp=val-add[i];
 72         ll id=lower_bound(b+l[i],b+r[i]+1,tmp)-(b+l[i]);
 73         ans+=id;
 74     }
 75     return ans;
 76 }
 77 int main()
 78 {
 79  //  freopen("hqx.in","r",stdin);
 80     scanf("%d",&n);
 81     for(int i=1; i<=n; i++)
 82     {
 83         scanf("%lld",&a[i]);
 84         b[i]=a[i];
 85     }
 86     buildblock();
 87     ll op,st,ed;
 88     ll val;
 89     while(n--)
 90     {
 91         scanf("%lld %lld %lld %lld",&op,&st,&ed,&val);
 92         if(op==0)
 93         {
 94             update(st,ed,val);
 95         }
 96         else if(op==1)
 97         {
 98             printf("%lld\n",ask(st,ed,val*val));
 99         }
100     }
101     return 0;
102 }

猜你喜欢

转载自www.cnblogs.com/letlifestop/p/10464427.html