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 }
  • 相关阅读:
    Generate SQL from Excel
    ASP.NET Web API系列教程目录
    进阶篇:以IL为剑,直指async/await
    30分钟?不需要,轻松读懂IL
    进程简介
    二维码详解
    通过IL分析C#中的委托、事件、Func、Action、Predicate之间的区别与联系
    我是一个线程
    ServiceLocator 简单示例(转)
    特性(C#)
  • 原文地址:https://www.cnblogs.com/Wangsheng5/p/11780736.html
Copyright © 2011-2022 走看看