数列分块入门 2

模板题:https://loj.ac/problem/6278

区间更新,区间查询

#include<bits/stdc++.h>
using namespace std;
#define maxn 50010
int a[maxn],belong[maxn],l[maxn],r[maxn],lazy[maxn],block,num,n;
vector<int>v[maxn];
void reset(int x)
{
    v[x].clear();
    for(int i=l[x];i<=r[x];i++)
        v[x].push_back(a[i]);
    sort(v[x].begin(),v[x].end());
}
void build()
{
    memset(lazy,0,sizeof(lazy));
    block=sqrt(n);
    num=n/block;
    if(n%block) num++;
    for(int i=1;i<=num;i++)
        l[i]=(i-1)*block+1,r[i]=i*block;
    r[num]=n;
    for(int i=1;i<=n;i++)
    {
        belong[i]=(i-1)/block+1;
        v[belong[i]].push_back(a[i]);
    }
     for(int i=1;i<=num;i++)
    {
        sort(v[i].begin(),v[i].end());
    }


}
void update(int left,int right,int c)
{
    if(belong[left]==belong[right])
    {

        for(int i=left;i<=right;i++)
        {
            a[i]+=c;
        }
        reset(belong[left]);
    }

    else
    {
        for(int i=left;i<=r[belong[left]];i++)
            a[i]+=c;
        reset(belong[left]);
        for(int i=l[belong[right]];i<=right;i++)
            a[i]+=c;
        reset(belong[right]);
        for(int i=belong[left]+1;i<=belong[right]-1;i++)
            lazy[i]+=c;
    }
}
void query(int left,int right,int c)
{
    int ans=0;
    if(belong[left]==belong[right])
    {
        for(int i=left;i<=right;i++)
            if(a[i]+lazy[belong[left]]<c)
                ans++;
    }
    else
    {

        for(int i=left;i<=r[belong[left]];i++)
            if(a[i]+lazy[belong[left]]<c)
                ans++;
        for(int i=l[belong[right]];i<=right;i++)
            if(a[i]+lazy[belong[right]]<c)
                ans++;
        for(int i=belong[left]+1;i<=belong[right]-1;i++)
        {
            ans+=lower_bound(v[i].begin(),v[i].end(),c-lazy[i])-v[i].begin();
        }


    }
    cout<<ans<<endl;

}
int main()
{
    std::ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
         cin>>a[i];
         v[i].clear();
    }
    build();
    vector<int>::iterator it;
    //cout<<"BLOCK start end"<<endl;
    //for(int i=1;i<=num;i++)
     //   cout<<l[i]<<" "<<r[i]<<endl;
   // cout<<"*************"<<endl;
   // cout<<"every number belong"<<endl;
    //for(int i=1;i<=n;i++)
    //    cout<<belong[i]<<" ";
    //cout<<endl;
    //for(int i=1;i<=3;i++)
    //{
     //   for(it=v[i].begin();it!=v[i].end();it++)
      //      cout<<*it<<" ";
     //   cout<<endl;
   // }
    //cout<<"*************"<<endl;
    //for(int i=1;i<=n;i++)
    //    cout<<a[i]<<" ";
   // cout<<endl;
    for(int i=1;i<=n;i++)
    {
        int opt,left,right,c;
        cin>>opt>>left>>right>>c;
        if(!opt)
            update(left,right,c);
        else
            query(left,right,c*c);
    }
    return 0;

}
原文地址:https://www.cnblogs.com/eason9906/p/11754919.html