zoukankan      html  css  js  c++  java
  • LOJ #6279. 数列分块入门 3

    给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,询问区间内小于某个值 c 的前驱(比其小的最大元素)。

    先在每个块内排序,然后残块暴力,整块lower_bound。

    指针形式运用lower_bound一定要小心啊啊啊 (调了1h+)

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<vector>
     5 #include<cstring>
     6 #include<cmath>
     7 #define pb push_back
     8 #define lb lower_bound
     9 #define val(i) (v[i]+atag[bl[i]])
    10 using namespace std;
    11 
    12 const int Maxn = 50005*2;
    13 int v[Maxn],atag[Maxn],bl[Maxn];
    14 int opt,l,r,c,n,blo;
    15 vector<int> V[Maxn];
    16 
    17 void reset(int x){
    18     for(int i = (x-1)*blo+1;i <= min(n,x*blo);i++)
    19         V[x][(i-1)%blo] = v[i];
    20     sort(V[x].begin(),V[x].end());
    21 }
    22 
    23 void change(int l,int r,int c){
    24     if(l > r)return;
    25     if(bl[l] == bl[r]){
    26         for(int i = l;i <= r;i++)v[i] += c;
    27         reset(bl[l]); return;
    28     }
    29     for(int i = l;i <= bl[l]*blo;i++)v[i] += c;reset(bl[l]);
    30     for(int i = (bl[r]-1)*blo+1;i <= r;i++)v[i] += c;reset(bl[r]);
    31     for(int i = bl[l]+1;i < bl[r];i++)atag[i] += c;
    32 }
    33 
    34 int query(int l,int r,int c){
    35     if(l > r)return -1;
    36     int ans = -1;
    37     if(bl[l] == bl[r]){
    38         for(int i = l;i <= r;i++)
    39             if(ans < val(i)&&val(i) < c)ans = val(i);
    40         return ans;
    41     }
    42     for(int i = l;i <= bl[l]*blo;i++)
    43         if(ans < val(i)&&val(i) < c)ans = val(i);//
    44     for(int i = (bl[r]-1)*blo+1;i <= r;i++)
    45         if(ans < val(i)&&val(i) < c)ans = val(i);//
    46     for(int i = bl[l]+1;i < bl[r];i++){
    47         vector<int>::iterator x = lb(V[i].begin(),V[i].end(),c-atag[i]);
    48         if(x == V[i].begin())continue;x--;
    49         while(x != V[i].begin()&&*x >= c-atag[i])x--;
    50         if(ans-atag[i] < *x&&*x < c-atag[i])ans = *x+atag[i];
    51     }
    52     return ans;
    53 }
    54 
    55 int main(){
    56     scanf("%d",&n);blo = sqrt(n);
    57     for(int i = 1;i <= n;i++){
    58         scanf("%d",&v[i]);
    59         bl[i] = (i-1)/blo+1;
    60         V[bl[i]].pb(v[i]);
    61     }
    62     for(int i = 1;i <= bl[n];i++)
    63         sort(V[i].begin(),V[i].end());
    64     for(int i = 1;i <= n;i++){
    65         scanf("%d%d%d%d",&opt,&l,&r,&c);
    66         if(opt == 1)printf("%d
    ",query(l,r,c));
    67         if(opt == 0)change(l,r,c);
    68     }    
    69 return 0;
    70 }
  • 相关阅读:
    shell笔记
    全引用与部分引用
    R语言 EFA(探索性因子分析)
    Markdown 基本使用
    Oracle截取字符串和查找字符串
    ggplot画基本图形类型
    ggplot画图笔记
    用R语言 画条形图(基于ggplot2包)
    Git基本操作
    R语言为数据框添加列名或行名
  • 原文地址:https://www.cnblogs.com/Wangsheng5/p/11781018.html
Copyright © 2011-2022 走看看