• #6279. 数列分块入门 3(询问区间内小于某个值 xx 的前驱(比其小的最大元素))


    题目链接:https://loj.ac/problem/6279

    题目大意:中文题目

    具体思路:按照上一个题的模板改就行了,但是注意在整块查找的时候的下标问题。

    AC代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 # define ll long long
      4 const int maxn =  2e5+100;
      5 const int mod = 1e8+7;
      6 const int inf = 0x3f3f3f3f;
      7 ll l[maxn],r[maxn],belong[maxn];
      8 ll add[maxn],a[maxn],b[maxn];
      9 int n;
     10 void buildblock()
     11 {
     12     ll tmp=(ll)sqrt(n);
     13     ll tot=n/tmp;
     14     if(n%tmp)
     15         tot++;
     16     for(ll i=1; i<=n; i++)
     17     {
     18         belong[i]=(i-1)/tmp+1ll;
     19     }
     20     for(ll  i=1; i<=tot; i++)
     21     {
     22         l[i]=(i-1)*tmp+1ll;
     23         r[i]=i*tmp;
     24     }
     25     r[tot]=n;
     26     for(ll i=1; i<=tot; i++)
     27     {
     28         sort(b+l[i],b+r[i]+1);
     29     }
     30 }
     31 void init(int tmp){
     32     for(int i=l[tmp];i<=r[tmp];i++)b[i]=a[i];
     33     sort(b+l[tmp],b+r[tmp]+1);
     34 }
     35 void update(ll st,ll ed,ll val)
     36 {
     37     if(belong[st]==belong[ed])
     38     {
     39         for(ll i=st; i<=ed; i++)a[i]+=val;
     40         init(belong[st]);
     41         return ;
     42     }
     43     for(ll i=st; i<=r[belong[st]]; i++)a[i]+=val;
     44     init(belong[st]);
     45     for(ll  i=l[belong[ed]]; i<=ed; i++)a[i]+=val;
     46     init(belong[ed]);
     47     for(ll i=belong[st]+1; i<belong[ed]; i++)
     48         add[i]+=val;
     49 }
     50 ll ask(ll st,ll ed,ll val)
     51 {
     52     ll ans=-inf;
     53     if(belong[st]==belong[ed])
     54     {
     55         for(ll i=st; i<=ed; i++)
     56         {
     57             if(a[i]+add[belong[st]]>=val)continue;
     58             ans=max(ans,a[i]+add[belong[st]]);
     59         }
     60         return ans;
     61     }
     62     for(ll i=st; i<=r[belong[st]]; i++)
     63     {
     64         if(a[i]+add[belong[st]]>=val)continue;
     65             ans=max(ans,a[i]+add[belong[st]]);
     66     }
     67     for(ll i=l[belong[ed]]; i<=ed; i++)
     68     {
     69        if(a[i]+add[belong[ed]]>=val)continue;
     70             ans=max(ans,a[i]+add[belong[ed]]);
     71     }
     72     for(ll i=belong[st]+1; i<belong[ed]; i++)
     73     {
     74         ll tmp=val-add[i];
     75         ll id=lower_bound(b+l[i],b+r[i]+1,tmp)-(b+l[i]);
     76         if(id==0)continue;
     77         ans=max(ans,b[l[i]+id-1]+add[i]);
     78     }
     79     return ans;
     80 }
     81 int main()
     82 {
     83  //  freopen("hqx.in","r",stdin);
     84 // cout<<lower_bound(a,a+5,2)-a<<endl;
     85     scanf("%d",&n);
     86     for(int i=1; i<=n; i++)
     87     {
     88         scanf("%lld",&a[i]);
     89         b[i]=a[i];
     90     }
     91     buildblock();
     92     ll op,st,ed;
     93     ll val;
     94     while(n--)
     95     {
     96         scanf("%lld %lld %lld %lld",&op,&st,&ed,&val);
     97         if(op==0)
     98         {
     99             update(st,ed,val);
    100         }
    101         else if(op==1)
    102         {
    103             ll tmp=ask(st,ed,val);
    104             printf("%lld
    ",tmp==-inf?-1:tmp);
    105         }
    106     }
    107     return 0;
    108 }
  • 相关阅读:
    P2764 最小路径覆盖问题
    P1402 酒店之王 网络流
    P2597 [ZJOI2012]灾难 拓扑排序
    FJOI2017 矩阵填数
    2019.2.27模拟
    2019.2.26模拟
    SDOI2013 方程
    [AH2017/HNOI2017]抛硬币
    Lucas定理和扩展Lucas定理
    LuoguP4861 按钮
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10465946.html
Copyright © 2020-2023  润新知