zoukankan      html  css  js  c++  java
  • #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
    ",ask(st,ed,val*val));
     99         }
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    nj07---npm
    nj06---包
    nj05---模块
    nj04---事件回调函数
    nj03---阻塞和线程
    nodejs02---demo
    nodejs简介
    【转贴】内存系列一:快速读懂内存条标签
    【转贴】4个你未必知道的内存小知识
    Linux上面mount 域控的目录 超时 然后提示 error的解决办法
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10464427.html
Copyright © 2011-2022 走看看