分析:这个题和bc round 73应该是差不多的题,当时是zimpha巨出的,那个是取phi,这个是开根

吐槽:赛场上写的时候直接维护数值相同的区间,然后1A,结果赛后糖教一组数据给hack了,仰慕

由于是开根,所以存在两个数刚开始差为1,加上某数再开根依旧是差1,这样维护相同数区间的就没用了

比如(2,3) +6-->(8,9)开根-->(2,3)如果全是这样的操作,即使维护相同的数,每次开根的复杂度都是O(N),不T才怪

这样只需要维护区间最大值最小值,当差1的时候,看看是否开根后还是差1,这样就可以变开根为减了

加强数据后,1591ms。。。(还是太年轻)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
typedef long long LL;
const int BufferSize=<<;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=,f=;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c=='-') f=-;
for(;isdigit(c);c=Getchar()) x=x*+c-'';
return x*f;
}
const int N=1e5+;
LL sum[N<<],lz[N<<],mx[N<<],mn[N<<];
void up(int rt){
sum[rt]=sum[rt<<]+sum[rt<<|];
mx[rt]=max(mx[rt<<],mx[rt<<|]);
mn[rt]=min(mn[rt<<],mn[rt<<|]);
}
void build(int rt,int l,int r){
lz[rt]=;
if(l==r){sum[rt]=read();mn[rt]=mx[rt]=sum[rt];return;}
int mid=l+r>>;
build(rt<<,l,mid);build(rt<<|,mid+,r);
up(rt);
}
void down(int rt,int l,int r){
if(lz[rt]!=){
int mid=l+r>>;
lz[rt<<]+=lz[rt];
lz[rt<<|]+=lz[rt];
mn[rt<<]+=lz[rt];
mx[rt<<]+=lz[rt];
mx[rt<<|]+=lz[rt];
mn[rt<<|]+=lz[rt];
sum[rt<<]+=lz[rt]*(mid-l+);
sum[rt<<|]+=lz[rt]*(r-mid);
lz[rt]=;
}
}
int x,y,t,T,n,m;
void kaigen(int rt,int l,int r){
if(x<=l&&r<=y){
if(mx[rt]==mn[rt]){
lz[rt]-=mx[rt];
mx[rt]=sqrt(mx[rt]);
mn[rt]=mx[rt];
lz[rt]+=mx[rt];
sum[rt]=mx[rt]*(r-l+);
return;
}
else if(mx[rt]==mn[rt]+){
LL x1=sqrt(mx[rt]);
LL x2=sqrt(mn[rt]);
if(x1==x2+){
lz[rt]-=(mx[rt]-x1);
sum[rt]-=(mx[rt]-x1)*(r-l+);
mx[rt]=x1;mn[rt]=x2;
return;
}
}
}
int mid=l+r>>;down(rt,l,r);
if(x<=mid)kaigen(rt<<,l,mid);
if(y>mid)kaigen(rt<<|,mid+,r);
up(rt);
}
void add(int rt,int l,int r){
if(x<=l&&r<=y){
lz[rt]+=t;
sum[rt]+=1ll*(r-l+)*t;
mx[rt]+=t;mn[rt]+=t;
return ;
}
int mid=l+r>>;down(rt,l,r);
if(x<=mid)add(rt<<,l,mid);
if(y>mid)add(rt<<|,mid+,r);
up(rt);
}
LL get(int rt,int l,int r){
if(x<=l&&r<=y)return sum[rt];
int mid=l+r>>;down(rt,l,r);
LL ret=;
if(x<=mid)ret+=get(rt<<,l,mid);
if(y>mid)ret+=get(rt<<|,mid+,r);
return ret;
}
int main(){
T=read();
while(T--){
n=read();m=read();
build(,,n);
while(m--){
int op;
op=read();x=read();y=read();
if(op==){
t=read();add(,,n);
}
else if(op==)kaigen(,,n);
else printf("%I64d\n",get(,,n));
}
}
return ;
}

最新文章

  1. 理清Java中的编码解码转换
  2. 计算机病毒实践汇总六:IDA Pro基础
  3. Web 开发人员和设计师必读文章推荐【系列三十】
  4. KVO内部实现原理
  5. windows临界区
  6. 多线程技术 NSThread &amp; NSOperation &amp; GCD
  7. 递归,回溯,DFS,BFS的理解和模板【摘】
  8. xcode针对不同IOS版本的代码编译问题
  9. CSS常用操作-对齐
  10. linux-Python升级安装
  11. OpenCV探索之路(三):滤波操作
  12. 小草手把手教你 LabVIEW 串口仪器控制——VISA 串口配置
  13. python爬虫之scrapy安装(一)
  14. Kafka技术内幕 读书笔记之(六) 存储层——服务端处理读写请求、分区与副本
  15. 770. Basic Calculator IV
  16. Spring/Spring MVC/Spring Boot的区别
  17. zuul学习
  18. Renderer.materials 和sharedMaterials一些用法上的区别
  19. 2016级算法第三次上机-E.ModricWang&#39;s Polygons
  20. 用Scanner读文本文件内容

热门文章

  1. MDK5.01百度云下载,安装微软雅黑混合字体,字体效果很棒,解决显示中文的BUG
  2. Linux命令(3):wc命令
  3. SSIS -&gt;&gt; Null &amp; Null Functions
  4. Android:在eclipse中快速多行注释的方法
  5. Java安全编码之用户输入
  6. Java —— 时区(夏令时)问题
  7. Qt之密码框不可选中、复制、粘贴、无右键菜单等
  8. windows 勾子简介
  9. Hadoop实战课程
  10. tomcat启动出错(转)