1、分块 (区间加法,查询小于x的个数)

 

技巧:开vector对区间sort,注意每次暴力更新的区间需要重新把数据放入vector中。

https://loj.ac/problem/6278

#include <algorithm>
#include  <iterator>
#include  <iostream>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
#include   <cassert>

using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue



typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3;

//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n'
//#define R register
#define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
#define REP(i , j , k)  for(int i = j ; i <  k ; ++i)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c);
//priority_queue<int ,vector<int>, greater<int> >que;

const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
const int mod = 1e9+7;
const double esp = 1e-8;
const double PI=acos(-1.0);
const double PHI=0.61803399;    //黄金分割点
const double tPHI=0.38196601;


template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x=f?-x:x;
}


/*-----------------------showtime----------------------*/

            const int maxn = 50009;
            ll a[maxn];
            ll sum[maxn];
            vector<ll>s[1009];
            int belong[maxn];
int main(){
            int n;  scanf("%d", &n);
            for(int i=1; i<=n; i++) scanf("%lld", &a[i]);
            int block = sqrt(n);
            int num = n/block; if(n%block) num++;
            for(int i=1; i<=n; i++)
            {
                belong[i] = (i-1)/block + 1;
                s[belong[i]].pb(a[i]);
            }
            for(int i=1; i<=num; i++) sort(s[i].begin(),s[i].end());
            int m = n;
            for(int i=1; i<=m; i++){
                int op;scanf("%d", &op);
                if(op == 0){
                    int l,r; ll x;
                    scanf("%d%d%lld", &l, &r, &x);

                     int id = belong[l],le = (belong[l]-1)*block+1;
                     if(belong[l] == belong[r]){
                        for(int i=l; i<=r; i++) a[i] += x;
                        s[id].clear();
                        for(int i=le; i<= belong[l]*block; i++) s[id].pb(a[i]);
                        sort(s[id].begin(),s[id].end());
                        continue;
                     }

                     for(int i=l; i<=belong[l]*block; i++) a[i] += x;
                     s[id].clear();
                     for(int i=le; i<= belong[l]*block; i++) s[id].pb(a[i]);
                     sort(s[id].begin(),s[id].end());

                     for(int i=belong[l]+1; i<=belong[r]-1; i++){
                        sum[i] += x;
                     }

                     int rid = belong[r],rle = (rid - 1) * block + 1;
                     for(int i=(rid-1)*block+1; i<=r; i++) a[i]+=x;
                     s[rid].clear();
                     for(int i=rle; i<=min(n, belong[r]*block) ; i++) s[rid].pb(a[i]);

                     sort(s[belong[r]].begin(),s[belong[r]].end());
                }
                else {
                        int l,r; ll x;
                        scanf("%d%d%lld", &l, &r, &x);
                        int cnt = 0;
                        if(belong[l] == belong[r]){
                            for(int i = l; i<= r; i++){
                                if(a[i] + sum[belong[i]] < 1ll*x*x) cnt++;
                            }
                        }
                        else {
                            for(int i=l; i<=belong[l]*block; i++)
                                if(a[i] + sum[belong[i]] < 1ll*x*x) cnt++;
                            for(int i=belong[l]+1; i<=belong[r]-1; i++){
                                cnt += lower_bound(s[i].begin(),s[i].end(), 1ll*x*x-sum[i]) - s[i].begin();
                            }
                            for(int i=(belong[r]-1)*block+1; i<=r; i++)
                                if(a[i] + sum[belong[i]] < 1ll*x*x) cnt++;
                        }
                        printf("%d\n", cnt);
                }
            }
            return 0;
}
View Code

相关文章:

  • 2021-07-21
  • 2021-10-06
  • 2021-12-31
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-08
猜你喜欢
  • 2021-10-30
  • 2022-01-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-19
  • 2022-02-23
  • 2021-10-01
相关资源
相似解决方案