zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    HDU 1114 Piggy-Bank
    HDU 2955 Robberies
    NTOJ 290 动物统计(加强版)
    POJ 3624 Charm Bracelet
    HDU 2602 Bone Collector
    POJ 1523 SPF(无向图割顶)
    HDU 5311 Hidden String
    HDU 1421 搬寝室
    HDU 1058 Humble Numbers
    POJ 3259 Wormholes(spfa判负环)
  • 原文地址:https://www.cnblogs.com/Wangsheng5/p/11780736.html
Copyright © 2011-2022 走看看