[LOJ6279]数列分块入门 3
2024-08-28 18:25:59
题目大意:
给你一个长度为$n(n\leq100000)$的序列$A$,支持进行以下两种操作:
1.将区间$[l,r]$中所有数加上$c$;
2.询问区间$[l,r]$中,严格小于$c$的最大数。
思路:
分块。
#include<cmath>
#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return neg?-x:x;
}
const int N=;
int val[N],tag[N],bel[N],s[N],begin[N],end[N];
inline bool cmp(const int &a,const int &b) {
return val[a]+tag[bel[a]]<val[b]+tag[bel[b]];
}
inline void modify(const int &l,const int &r,const int &c) {
if(bel[l]==bel[r]) {
for(register int i=l;i<=r;i++) val[i]+=c;
std::sort(&s[begin[bel[l]]],&s[end[bel[l]]]+,cmp);
return;
}
for(register int i=l;bel[i]==bel[l];i++) val[i]+=c;
std::sort(&s[begin[bel[l]]],&s[end[bel[l]]]+,cmp);
for(register int i=r;bel[i]==bel[r];i--) val[i]+=c;
std::sort(&s[begin[bel[r]]],&s[end[bel[r]]]+,cmp);
for(register int i=bel[l]+;i<bel[r];i++) tag[i]+=c;
}
inline int query(const int &l,const int &r,const int &c) {
int ret=INT_MIN;
bool flag=false;
if(bel[l]==bel[r]) {
for(register int i=l;i<=r;i++) {
if(val[i]+tag[bel[i]]<c) {
ret=std::max(ret,val[i]+tag[bel[i]]);
flag=true;
}
}
return flag?ret:-;
}
for(register int i=l;bel[i]==bel[l];i++) {
if(val[i]+tag[bel[i]]<c) {
ret=std::max(ret,val[i]+tag[bel[i]]);
flag=true;
}
}
for(register int i=r;bel[i]==bel[r];i--) {
if(val[i]+tag[bel[i]]<c) {
ret=std::max(ret,val[i]+tag[bel[i]]);
flag=true;
}
}
for(register int i=bel[l]+;i<bel[r];i++) {
const int pos=std::lower_bound(&s[begin[i]],&s[end[i]]+,,cmp)-&s[];
if(pos!=begin[i]) {
ret=std::max(ret,val[s[pos-]]+tag[bel[s[pos-]]]);
flag=true;
}
}
return flag?ret:-;
}
int main() {
const int n=getint(),block=sqrt(n);
for(register int i=;i<=n;i++) {
val[i]=getint();
bel[i]=i/block+;
s[i]=i;
if(!begin[bel[i]]) begin[bel[i]]=i;
end[bel[i]]=i;
}
for(register int i=bel[];i<=bel[n];i++) {
std::sort(&s[begin[i]],&s[end[i]]+,cmp);
}
for(register int i=;i<n;i++) {
const int opt=getint(),l=getint(),r=getint(),&c=val[]=getint();
if(opt) {
printf("%d\n",query(l,r,c));
} else {
modify(l,r,c);
}
}
return ;
}
最新文章
- 清空Fragment回退栈中某个Fragment
- 回忆那些我们曾今铭记过的.NET重点知识
- 【scikit-learn】scikit-learn的线性回归模型
- Windows下 VM12虚拟机安装OS X 10.11 和VM TOOLS
- Nginx 下配置SSL证书的方法
- 转:ecshop商品分类页获取相册列表方法
- 2015年百度之星初赛(1) --- C 序列变换
- JavaEE基础(十七)/集合
- jQuery的单选,复选,下拉
- centos kvm
- SSO单点登录的实现原理
- vim插件
- Linux笔记(九) - 软件包管理
- 简单的记录,VMware Tools的安装
- 深度剖析linux内核万能--双向链表,Hash链表模版
- 吴恩达《机器学习》课程笔记——第六章:Matlab/Octave教程
- Python爬虫入门教程 22-100 CSDN学院课程数据抓取
- 区块链代币(Token)笔记 — — 术语
- Windows10 正式企业版激活
- 刘志梅201771010115.《面向对象程序设计(java)》第十七周学习总结