#6279. 数列分块入门 3

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

提交提交记录统计测试数据讨论

3

题目描述

给出一个长为 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 的前驱的值(不存在则输出 -1−1)。

输出格式

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

样例

样例输入

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}1≤n≤100000,−231≤others、\mathrm{ans} \leq 2^{31}-1ans≤231−1。

代码:

  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\n",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 */

转载于:https://www.cnblogs.com/ZERO-/p/10525655.html

LOJ #6279. 数列分块入门 3-分块(区间加法、查询区间内小于某个值x的前驱(比其小的最大元素))...相关推荐

  1. LOJ #6280. 数列分块入门 4-分块(区间加法、区间求和)

    #6280. 数列分块入门 4 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 题目描述 给出一个长为 ...

  2. HDU - 4578Transformation——线段树+区间加法修改+区间乘法修改+区间置数+区间和查询+区间平方和查询+区间立方和查询

    [题目描述] HDU - 4578Transformation Problem Description Yuanfang is puzzled with the question below: The ...

  3. LibreOJ 6279 数列分块入门 3(分块+排序)

    题解:自然是先分一波块,把同一个块中的所有数字压到一个vector中,将每一个vector进行排序.然后对于每一次区间加,不完整的块加好后暴力重构,完整的块直接修改标记.查询时不完整的块暴力找最接近x ...

  4. 数据结构:分块-区间加法、区间乘法和单点查询

    这里问题的关键是妥善处理好两种标记 让乘法标记的优先级高于加法 若当前的一个块乘以m1后加上a1,这时进行一个乘m2的操作,则原来的标记变成m1*m2,a1*m2 若当前的一个块乘以m1后加上a1,这 ...

  5. leetcode 436. Find Right Interval | 436. 寻找右区间(二分查找不小于某值的第一个位置)

    题目 https://leetcode.com/problems/find-right-interval/ 题解 这题考察点不难,就是个普通的二分查找.详细过程是: 因为 start 是唯一的,所以先 ...

  6. 【分块入门】LOJ 数列分块入门 1 - 9 (学习更新……)

    dl题解 _「分块」数列分块入门1 – 9 by hzwer LOJ #6277. 数列分块入门 1 题意:给出一个长为n的数列,以及n个操作,操作涉及区间加法,单点查值. 时间限制:100ms 分块 ...

  7. LOJ——#6277. 数列分块入门 1

    ~~推荐播客~~ 「分块」数列分块入门1 – 9 by hzwer 浅谈基础根号算法--分块 博主蒟蒻,有缘人可直接观摩以上大佬的博客... #6277. 数列分块入门 1 题目大意: 给出一个长为 ...

  8. 数列分块入门 3(LibreOj-6279)

    [题目描述] 给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,询问区间内小于某个值 x 的前驱(比其小的最大元素). [输入格式] 第一行输入一个数字 n. 第二行输入 n 个数字,第 ...

  9. LibreOJ 数列分块入门

    题目链接:https://loj.ac/problem/6277 题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字 nnn. 第 ...

最新文章

  1. 连接池和 Timeout expired异常
  2. 备忘录:CISCO router ENABLE crack
  3. boost::prior用法的测试程序
  4. leetcode904. 水果成篮(滑动窗口)
  5. 数据结构 旅游规划(Dijkstra+Dfs)
  6. C语言 scanf()和gets()函数的区别
  7. Android安卓|安卓概述、安卓开发、安卓入门、安卓架构
  8. java实现socket连接,向指定主机指定端口发送socket数据,并获取响应数据
  9. sniffer经典指南 一
  10. LineageOS源码定制手机系统
  11. React.js 小书 阅读笔记3
  12. 功能安全标准-ISO26262-8---安全分析手段FIA,FMEA,FMEDA
  13. docker源码编译安装步骤解析
  14. PMP知识点总结—计算题汇总
  15. 以什么样的模式和方式来解决问题或创造价值?
  16. 用Angular实现图片上传问题
  17. 会声会影2018 转码导出H.265/HEVC编码视频
  18. python如何检测文件或图片类型
  19. Zabbix以trapper方式监控MySQL备份文件
  20. 用Java抓取10年大乐透中奖数据

热门文章

  1. 《仰天大笑出门去,这个杀手有脾气-雾满拦江》
  2. LeetCode学习-查找2-合并版
  3. gitpc段提交失败schannel: next InitializeSecurityContext failed: Unknown error (0x80092013
  4. python苹果手机照片导入电脑_iphone照片怎么导入电脑?四种方法汇总
  5. MEMOS 技术支持
  6. Ubuntu下安装微信(非网页版)、TIM、QQ
  7. 互联网产品经理职业规划图(转载)
  8. java实现手机验证码功能
  9. 超声波传感器介绍及其使用(STM32)
  10. 牛客网 15029 (栈)