• LOJ #6278. 数列分块入门 2


    hzwer tql!

    渐渐找到了分块的套路。

    给出一个长为  n 的数列,以及 n 个操作,操作涉及区间加法,询问区间内小于某个值 c*c 的元素个数。

    残块先在原数组上暴力,然后拿原数组更新块数组(效率高于结构体存id!),整块就标记。

    code:

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<vector>
     6 #define pb push_back
     7 #define lb lower_bound
     8 using namespace std;
     9 
    10 const int Maxn = 50005; 
    11 
    12 vector<int> V[Maxn];
    13 int bl[Maxn],v[Maxn],atag[Maxn];
    14 int n,blo,l,r,opt,c;
    15 
    16 void reset(int x){
    17     for(int i = (x-1)*blo+1;i <= min(n,x*blo);i++)
    18         V[x][(i-1)%blo] = v[i];
    19     sort(V[x].begin(),V[x].end());
    20 } 
    21 
    22 void add(int l,int r,int c){
    23     if(bl[l] == bl[r]){
    24         for(int i = l;i <= r;i++)v[i] += c;
    25         reset(bl[r]);return;
    26     }
    27     for(int i = l;i <= min(n,bl[l]*blo);i++)v[i] += c;reset(bl[l]);
    28     for(int i = (bl[r]-1)*blo+1;i <= r;i++)v[i] += c;reset(bl[r]);
    29     for(int i = bl[l]+1;i < bl[r];i++)atag[i] += c;
    30 }
    31 
    32 int ask(int l,int r,int c2){
    33     if(l > r)return 0;
    34     int cnt = 0;
    35     if(bl[l] == bl[r]){
    36         for(int i = l;i <= r;i++)if(v[i]+atag[bl[i]] < c2)cnt++;
    37         return cnt;
    38     }
    39     for(int i = l;i <= min(bl[l]*blo,n);i++)
    40         if(v[i]+atag[bl[i]] < c2)cnt++;
    41     for(int i = (bl[r]-1)*blo+1;i <= min(r,n);i++)
    42         if(v[i]+atag[bl[i]] < c2)cnt++;
    43     for(int i = bl[l]+1;i < bl[r];i++)
    44         cnt += lb(V[i].begin(),V[i].end(),c2-atag[i])-V[i].begin();
    45     return cnt;
    46 }
    47 
    48 int main(){
    49     scanf("%d",&n);blo = sqrt(n);
    50     for(int i = 1;i <= n;i++){
    51         scanf("%d",&v[i]);
    52         bl[i] = (i-1)/blo+1;
    53         V[bl[i]].pb(v[i]);
    54     }
    55     for(int i = 1;i <= bl[n];i++)sort(V[i].begin(),V[i].end());
    56     for(int i = 1;i <= n;i++){
    57         scanf("%d%d%d%d",&opt,&l,&r,&c);
    58         if(opt)printf("%d
    ",ask(l,r,c*c));
    59         else add(l,r,c);
    60     }
    61 return 0;
    62 }
  • 相关阅读:
    session 和 aplication 相关总结
    asp.net网站发布时碰到的一些问题
    考前防脑瘫防挂分预防针
    【游记】NOIP2021 白给记
    SELECT list is not in GROUP BY clause and contains nonaggregated
    StringUtils.isEmpty()
    gitLab生成SSH私钥后上传代码及获取代码
    tomcat配置https请求访问
    Mybatis:映射文件概述 & 增删改查
    Mybatis:核心文件概述
  • 原文地址:https://www.cnblogs.com/Wangsheng5/p/11780736.html
Copyright © 2020-2023  润新知