题目大意:
  给你一个长度为$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 ;
}

最新文章

  1. 清空Fragment回退栈中某个Fragment
  2. 回忆那些我们曾今铭记过的.NET重点知识
  3. 【scikit-learn】scikit-learn的线性回归模型
  4. Windows下 VM12虚拟机安装OS X 10.11 和VM TOOLS
  5. Nginx 下配置SSL证书的方法
  6. 转:ecshop商品分类页获取相册列表方法
  7. 2015年百度之星初赛(1) --- C 序列变换
  8. JavaEE基础(十七)/集合
  9. jQuery的单选,复选,下拉
  10. centos kvm
  11. SSO单点登录的实现原理
  12. vim插件
  13. Linux笔记(九) - 软件包管理
  14. 简单的记录,VMware Tools的安装
  15. 深度剖析linux内核万能--双向链表,Hash链表模版
  16. 吴恩达《机器学习》课程笔记——第六章:Matlab/Octave教程
  17. Python爬虫入门教程 22-100 CSDN学院课程数据抓取
  18. 区块链代币(Token)笔记 — — 术语
  19. Windows10 正式企业版激活
  20. 刘志梅201771010115.《面向对象程序设计(java)》第十七周学习总结

热门文章

  1. 牛客网暑期ACM多校训练营(第一场):J-Different Integers(分开区间不同数+树状数组)
  2. 原始套接字--traceroute
  3. (总结)Nginx与Apache、Tomcat、Resin动静分离核心配置
  4. sql优化(转)
  5. Bsd内核选项总结
  6. [bzoj3270] 博物馆 [期望+高斯消元]
  7. 《c程序设计语言》读书笔记-5.8-天数和日期转换错误检查
  8. Pandas之Series
  9. Mysql事务隔离级
  10. myeclipse 常规web项目创建