LOJ #6279. 数列分块入门 3-分块(区间加法、查询区间内小于某个值x的前驱(比其小的最大元素))...
#6279. 数列分块入门 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的前驱(比其小的最大元素))...相关推荐
- LOJ #6280. 数列分块入门 4-分块(区间加法、区间求和)
#6280. 数列分块入门 4 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 题目描述 给出一个长为 ...
- HDU - 4578Transformation——线段树+区间加法修改+区间乘法修改+区间置数+区间和查询+区间平方和查询+区间立方和查询
[题目描述] HDU - 4578Transformation Problem Description Yuanfang is puzzled with the question below: The ...
- LibreOJ 6279 数列分块入门 3(分块+排序)
题解:自然是先分一波块,把同一个块中的所有数字压到一个vector中,将每一个vector进行排序.然后对于每一次区间加,不完整的块加好后暴力重构,完整的块直接修改标记.查询时不完整的块暴力找最接近x ...
- 数据结构:分块-区间加法、区间乘法和单点查询
这里问题的关键是妥善处理好两种标记 让乘法标记的优先级高于加法 若当前的一个块乘以m1后加上a1,这时进行一个乘m2的操作,则原来的标记变成m1*m2,a1*m2 若当前的一个块乘以m1后加上a1,这 ...
- leetcode 436. Find Right Interval | 436. 寻找右区间(二分查找不小于某值的第一个位置)
题目 https://leetcode.com/problems/find-right-interval/ 题解 这题考察点不难,就是个普通的二分查找.详细过程是: 因为 start 是唯一的,所以先 ...
- 【分块入门】LOJ 数列分块入门 1 - 9 (学习更新……)
dl题解 _「分块」数列分块入门1 – 9 by hzwer LOJ #6277. 数列分块入门 1 题意:给出一个长为n的数列,以及n个操作,操作涉及区间加法,单点查值. 时间限制:100ms 分块 ...
- LOJ——#6277. 数列分块入门 1
~~推荐播客~~ 「分块」数列分块入门1 – 9 by hzwer 浅谈基础根号算法--分块 博主蒟蒻,有缘人可直接观摩以上大佬的博客... #6277. 数列分块入门 1 题目大意: 给出一个长为 ...
- 数列分块入门 3(LibreOj-6279)
[题目描述] 给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,询问区间内小于某个值 x 的前驱(比其小的最大元素). [输入格式] 第一行输入一个数字 n. 第二行输入 n 个数字,第 ...
- LibreOJ 数列分块入门
题目链接:https://loj.ac/problem/6277 题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字 nnn. 第 ...
最新文章
- 连接池和 Timeout expired异常
- 备忘录:CISCO router ENABLE crack
- boost::prior用法的测试程序
- leetcode904. 水果成篮(滑动窗口)
- 数据结构 旅游规划(Dijkstra+Dfs)
- C语言 scanf()和gets()函数的区别
- Android安卓|安卓概述、安卓开发、安卓入门、安卓架构
- java实现socket连接,向指定主机指定端口发送socket数据,并获取响应数据
- sniffer经典指南 一
- LineageOS源码定制手机系统
- React.js 小书 阅读笔记3
- 功能安全标准-ISO26262-8---安全分析手段FIA,FMEA,FMEDA
- docker源码编译安装步骤解析
- PMP知识点总结—计算题汇总
- 以什么样的模式和方式来解决问题或创造价值?
- 用Angular实现图片上传问题
- 会声会影2018 转码导出H.265/HEVC编码视频
- python如何检测文件或图片类型
- Zabbix以trapper方式监控MySQL备份文件
- 用Java抓取10年大乐透中奖数据
热门文章
- 《仰天大笑出门去,这个杀手有脾气-雾满拦江》
- LeetCode学习-查找2-合并版
- gitpc段提交失败schannel: next InitializeSecurityContext failed: Unknown error (0x80092013
- python苹果手机照片导入电脑_iphone照片怎么导入电脑?四种方法汇总
- MEMOS 技术支持
- Ubuntu下安装微信(非网页版)、TIM、QQ
- 互联网产品经理职业规划图(转载)
- java实现手机验证码功能
- 超声波传感器介绍及其使用(STM32)
- 牛客网 15029 (栈)