zoukankan      html  css  js  c++  java
  • LOJ #6279. 数列分块入门 3-分块(区间加法、查询区间内小于某个值x的前驱(比其小的最大元素))

    内存限制:256 MiB时间限制:1500 ms标准输入输出
    题目类型:传统评测方式:文本比较
    上传者: hzwer

    题目描述

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

    输入格式

    第一行输入一个数字 nn。

    第二行输入 nn 个数字,第 ii 个数字为 a_iai,以空格隔开。

    接下来输入 nn 行询问,每行输入四个数字 mathrm{opt}opt、ll、rr、cc,以空格隔开。

    若 mathrm{opt} = 0opt=0,表示将位于 [l, r][l,r] 的之间的数字都加 cc。

    若 mathrm{opt} = 1opt=1,表示询问 [l, r][l,r] 中 cc 的前驱的值(不存在则输出 -11)。

    输出格式

    对于每次询问,输出一行一个数字表示答案。

    样例

    样例输入

    4
    1 2 2 3
    0 1 3 1
    1 1 4 4
    0 1 2 2
    1 1 2 4

    样例输出

    3
    -1

    数据范围与提示

    对于 100\%100% 的数据,1 leq n leq 100000, -2^{31} leq mathrm{others}1n100000,231others、mathrm{ans} leq 2^{31}-1ans2311。

    代码:

      1 //#6279. 数列分块入门 3-区间加法,查询区间内小于某个值x的前驱(比其小的最大元素)
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 typedef long long ll;
      5 const int maxn=1e5+10;
      6 
      7 int n,m;
      8 ll a[maxn],b[maxn],pos[maxn],tag[maxn];
      9 
     10 void rechange(int x)
     11 {
     12     for(int i=(x-1)*m+1;i<=min(x*m,n);i++){
     13             b[i]=a[i];
     14     }
     15     sort(b+(x-1)*m+1,b+min(x*m,n)+1);
     16 }
     17 
     18 void update(int l,int r,ll c)
     19 {
     20     if(pos[l]==pos[r]){
     21         for(int i=l;i<=r;i++)
     22             a[i]+=c;
     23         rechange(pos[l]);
     24     }
     25     else{
     26         for(int i=l;i<=pos[l]*m;i++)
     27             a[i]+=c;
     28         rechange(pos[l]);
     29         for(int i=pos[l]+1;i<=pos[r]-1;i++)
     30             tag[i]+=c;
     31         for(int i=(pos[r]-1)*m+1;i<=r;i++)
     32             a[i]+=c;
     33         rechange(pos[r]);
     34     }
     35 }
     36 
     37 ll query(int l,int r,ll c)
     38 {
     39     ll ans=-1;
     40     if(pos[l]==pos[r]){
     41         for(int i=l;i<=r;i++){
     42             if(a[i]+tag[pos[l]]<c){
     43                 ans=max(ans,a[i]+tag[pos[l]]);
     44             }
     45         }
     46     }
     47     else{
     48         for(int i=l;i<=pos[l]*m;i++){
     49             if(a[i]+tag[pos[l]]<c){
     50                 ans=max(ans,a[i]+tag[pos[l]]);
     51             }
     52         }
     53         for(int i=pos[l]+1;i<=pos[r]-1;i++){
     54             int cnt=c-tag[i];
     55             int ret=lower_bound(b+(i-1)*m+1,b+i*m+1,cnt)-b-1;
     56             //cout<<ret<<" "<<(i-1)*m<<endl;
     57             if(ret!=(i-1)*m)
     58                 ans=max(ans,b[ret]+tag[i]);
     59         }
     60         for(int i=(pos[r]-1)*m+1;i<=r;i++){
     61             if(a[i]+tag[pos[r]]<c){
     62                 ans=max(ans,a[i]+tag[pos[r]]);
     63             }
     64         }
     65     }
     66     return ans;
     67 }
     68 
     69 int main()
     70 {
     71     scanf("%d",&n);
     72     m=sqrt(n);
     73     for(int i=1;i<=n;i++){
     74         scanf("%d",&a[i]);
     75         b[i]=a[i];
     76         pos[i]=(i-1)/m+1;
     77     }
     78     for(int i=1;i<=m+1;i++)
     79         sort(b+(i-1)*m+1,b+min(i*m,n)+1);
     80     for(int i=1;i<=n;i++){
     81         int op,l,r;
     82         ll c;
     83         scanf("%d%d%d%lld",&op,&l,&r,&c);
     84         if(op==0){
     85             update(l,r,c);
     86         }
     87         else{
     88             printf("%lld
    ",query(l,r,c));
     89         }
     90     }
     91 }
     92 
     93 
     94 /*
     95 10
     96 1 3 4 2 5 7 11 3 5 1
     97 0 1 5 1
     98 1 1 7 2
     99 0 3 9 1
    100 1 4 8 7
    101 1 1 10 6
    102 1 3 5 3
    103 1 5 10 7
    104 1 6 10 6
    105 1 2 7 4
    106 1 2 7 5
    107 
    108 -1
    109 4
    110 4
    111 -1
    112 6
    113 4
    114 -1
    115 4
    116 */
  • 相关阅读:
    Oracle 11g导出空表
    如何破解ROS路由器禁用路由PPPOE拨号?
    Oracle入门心得(2)
    ORACLE了局,每天10问(五)
    若何消除Oracle数据库的安静隐患(3)
    Oracle入门心得(1)
    ORACLE用户自定义备份与恢复条记
    ORACLE成绩,每天10问(三)
    ORACLE问题,每天10问(一)
    怎样消除Oracle数据库的安全隐患(1)
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10525655.html
Copyright © 2011-2022 走看看