http://uoj.ac/problem/228

参考:https://www.cnblogs.com/ljh2000-jump/p/6357583.html

考虑当整个区间的最大值开方==最小值开方(实质上就是区间开完方后所有数都相等),那么我们开一次方就可以了。

听说有证明如果达到上面的那种情况的话最多需要操作O(lg^2)次,那么复杂度就是O(n*lg^3)了。

实际上开方只是起到了一个缩小最大值和最小值差值的作用,当差值缩小为0时就是我们所想要的那种情况。

但是也有极端数据比如898989,开完方变成343434……无限下去你就会发现无论怎么开所有的数都会差1,复杂度瞬间被艹。

对于这种极端数据实际上只是进行了一次区间减,我们特判之就能保证复杂度了。

另外为了减少代码编写难度,采用了参考的那种只有当最大值==最小值才开方的写法,虽然最好情况下复杂度会增加,但是最坏情况复杂度并没有增加,所以没有问题。

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+;
inline ll read(){
ll X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
int n,m;
ll b[N],sum[N*],ad[N*],maxn[N*],minn[N*];
inline void mdy(int a,int l,int r,ll w){
sum[a]+=w*(r-l+);
maxn[a]+=w;minn[a]+=w;
ad[a]+=w;
}
inline void upt(int a,int l,int r){
int ls=a<<,rs=a<<|;
sum[a]=sum[ls]+sum[rs]+ad[a]*(r-l+);
maxn[a]=max(maxn[ls],maxn[rs])+ad[a];
minn[a]=min(minn[ls],minn[rs])+ad[a];
}
void build(int a,int l,int r){
if(l==r){
sum[a]=maxn[a]=minn[a]=b[l];
return;
}
int mid=(l+r)>>;
build(a<<,l,mid);build(a<<|,mid+,r);
upt(a,l,r);
}
void seg_add(int a,int l,int r,int l1,int r1,ll w){
if(r<l1||r1<l)return;
if(l1<=l&&r<=r1){
mdy(a,l,r,w);
return;
}
int mid=(l+r)>>;
seg_add(a<<,l,mid,l1,r1,w);seg_add(a<<|,mid+,r,l1,r1,w);
upt(a,l,r);
}
void seg_sqrt(int a,int l,int r,int l1,int r1,ll w){
if(r<l1||r1<l)return;
if(l1<=l&&r<=r1){
ll delta,c1=sqrt(minn[a]+w),c2=sqrt(maxn[a]+w);
if(maxn[a]==minn[a]){
delta=minn[a]+w-(ll)sqrt(minn[a]+w);
mdy(a,l,r,-delta);
return;
}else if(minn[a]+==maxn[a]&&c1+==c2){
delta=minn[a]+w-(ll)sqrt(minn[a]+w);
mdy(a,l,r,-delta);
return;
}
}
int mid=(l+r)>>;w+=ad[a];
seg_sqrt(a<<,l,mid,l1,r1,w);seg_sqrt(a<<|,mid+,r,l1,r1,w);
upt(a,l,r);
}
ll query(int a,int l,int r,int l1,int r1,ll w){
if(r<l1||r1<l)return ;
if(l1<=l&&r<=r1)return sum[a]+w*(r-l+);
int mid=(l+r)>>;w+=ad[a];
return query(a<<,l,mid,l1,r1,w)+query(a<<|,mid+,r,l1,r1,w);
}
int main(){
n=read(),m=read();
for(int i=;i<=n;i++)b[i]=read();
build(,,n);
while(m--){
int op=read(),x=read(),y=read();
if(op==)seg_add(,,n,x,y,read());
if(op==)seg_sqrt(,,n,x,y,);
if(op==)printf("%lld\n",query(,,n,x,y,));
}
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

UOJ228:基础数据结构练习题——题解的更多相关文章

  1. uoj228 基础数据结构练习题

    趁别人题解没有放出来赶快写一篇 整数序列,操作 区间加 区间变成sqrt(下取整) 区间和 考虑一下对于每个区间里所有sqrt不同的段操作,那么可以在O(段数logn)一次的时间内完成sqrt操作.考 ...

  2. [UOJ228] 基础数据结构练习题 - 线段树

    考虑到一个数开根号 \(loglog\) 次后就会变成1,设某个Node的势能为 \(loglog(maxv-minv)\) ,那么一次根号操作会使得势能下降 \(1\) ,一次加操作最多增加 \(l ...

  3. 【UOJ228】基础数据结构练习题(线段树)

    [UOJ228]基础数据结构练习题(线段树) 题面 UOJ 题解 我们来看看怎么开根? 如果区间所有值都相等怎么办? 显然可以直接开根 如果\(max-sqrt(max)=min-sqrt(min)\ ...

  4. 【UOJ#228】基础数据结构练习题 线段树

    #228. 基础数据结构练习题 题目链接:http://uoj.ac/problem/228 Solution 这题由于有区间+操作,所以和花神还是不一样的. 花神那道题,我们可以考虑每个数最多开根几 ...

  5. uoj #228. 基础数据结构练习题 线段树

    #228. 基础数据结构练习题 统计 描述 提交 自定义测试 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的 ...

  6. 【线段树】uoj#228. 基础数据结构练习题

    get到了标记永久化 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的好朋友九条可怜酱给她出了一道题. 给出一 ...

  7. 【uoj228】 基础数据结构练习题

    http://uoj.ac/problem/228 (题目链接) 题意 给出一个序列,维护区间加法,区间开根,区间求和 Solution 线段树.考虑区间开根怎么做.当区间的最大值与最小值相等时,我们 ...

  8. uoj228:基础数据结构练习题

    题意:http://uoj.ac/problem/228 sol  :线段树开根操作 对于节点x,可以在max[x]-min[x]<=1时直接做,转化为区间减或区间覆盖 #include< ...

  9. 【UOJ#228】 基础数据结构练习题

    题目描述 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的好朋友九条可怜酱给她出了一道题. 给出一个长度为 n ...

随机推荐

  1. Mybatis JPA 插件简介

    前段时间了解到Spring JPA,感觉挺好用,但其依赖于Hibernate,本人看到Hibernate就头大(不是说Hibernate不好哈,而是进阶太难),于是做了一个迷你版的Mybatis JP ...

  2. 深入理解javascript原型链

    在javascript中原型和原型链是一个很神奇的东西,对于大多数人也是最难理解的一部分,掌握原型和原型链的本质是javascript进阶的重要一环.今天我分享一下我对javascript原型和原型链 ...

  3. VS2015 更改C++模式

    亲爱的小伙伴,有没有发现你们的VS2015装完以后和老江湖们用的不一样了,人家的界面打开是这样的 而你的界面打开是这样的 虽然看是只有一左一右的区别,但是内在确实有好多不一样. 想不想想老江湖一样,拥 ...

  4. WEB安全--高级sql注入,爆错注入,布尔盲注,时间盲注

    1.爆错注入 什么情况想能使用报错注入------------页面返回连接错误信息 常用函数 updatexml()if...floorextractvalue updatexml(,concat() ...

  5. jenkins配置git+maven+Publish over SSH

    一.配置git 1.新建项目,源码管理选择git 2.Repository URL输入git目录 3.Credentials中选择新增凭据,凭据类型选择SSH,usename输入git,passphr ...

  6. 了解Python控制流语句——break 语句

    这篇文章主要介绍了详解Python中break语句的用法,是Python入门的呼出知识,需要的朋友可以参考下,python基础系列教程之-Python break语句 跳出循环 break 语句用以中 ...

  7. [问题] docker: Failed to start Docker Application Container Engine.

    docker无法启动: # systemctl restart docker Job for docker.service failed because the control process exi ...

  8. opencv-学习笔记(6)图像梯度Sobel以及canny边缘检测

    opencv-学习笔记(6)图像梯度Sobel以及canny边缘检测 这章讲了 sobel算子 scharr算子 Laplacion拉普拉斯算子 图像深度问题 Canny检测 图像梯度 sobel算子 ...

  9. MFC常用数据类型

    下面这些是和Win32程序共同使用的数据类型BOOL:布尔值,取值为TRUE or FALSEBSTR:32-bit 字符指针BYTE:8-bit整数,未带正负号COLORREF:32-bit数值,代 ...

  10. 20145214 《Java程序设计》第5周学习总结

    20145214 <Java程序设计>第5周学习总结 教材学习内容总结 try和catch Java中所有错误都会被包装为对象,可以尝试try执行程序并捕捉catch代表错误的对象后做一些 ...