Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Yuta has an array A with n numbers. Then he makes m operations on it.

There are three type of operations:

1 l r x : For each i in [l,r], change A[i] to A[i]+x
2 l r : For each i in [l,r], change A[i] to ⌊√A[i]⌋
3 l r : Yuta wants Rikka to sum up A[i] for all i in [l,r]

It is too difficult for Rikka. Can you help her?

Input
The first line contains a number t(1<=t<=100), the number of the testcases. And there are no more than 5 testcases with n>1000.

For each testcase, the first line contains two numbers n,m(1<=n,m<=100000). The second line contains n numbers A[1]~A[n]. Then m lines follow, each line describe an operation.

It is guaranteed that 1<=A[i],x<=100000.

Output
For each operation of type 3, print a lines contains one number -- the answer of the query.

Sample Input
1
5 5
1 2 3 4 5
1 3 5 2
2 1 4
3 2 4
2 3 5
3 1 5

Sample Output
5
6

题意

实现区间加,区间开根,区间求和

题解

一开始以为可以暴力开根,然后统计区间内是否全为1,后来发现开完根再加又可以开根所以单次复杂度就变成O(n)

后来发现区间开根会出现一大片相同的区域,所以可以再维护一个最大最小值,如果maxx[rt]-minn[rt]==(LL)sqrt(maxx[rt])-(LL)sqrt(minn[rt])||maxx[rt]==minn[rt]就说明区间开根后所有值都相同,那就可以直接更新区间

代码

 #include<bits/stdc++.h>
using namespace std; #define LL long long const int maxn=1e5+; LL sum[maxn<<],lazy[maxn<<],minn[maxn<<],maxx[maxn<<]; void pushdown(int l,int r,int rt)
{
if(lazy[rt]==)return;
lazy[rt<<]+=lazy[rt];
lazy[rt<<|]+=lazy[rt];
int mid=(l+r)>>;
sum[rt<<]+=lazy[rt]*(mid-l+);
sum[rt<<|]+=lazy[rt]*(r-mid);
maxx[rt<<]+=lazy[rt];
maxx[rt<<|]+=lazy[rt];
minn[rt<<]+=lazy[rt];
minn[rt<<|]+=lazy[rt];
lazy[rt]=;
}
void pushup(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];
minn[rt]=min(minn[rt<<],minn[rt<<|]);
maxx[rt]=max(maxx[rt<<],maxx[rt<<|]);
}
void build(int l,int r,int rt)
{
lazy[rt]=;
if(l==r)
{
scanf("%lld",&sum[rt]);
minn[rt]=maxx[rt]=sum[rt];
return;
}
int mid=(l+r)>>;
build(l,mid,rt<<);
build(mid+,r,rt<<|);
pushup(rt);
}
void update(int L,int R,LL C,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
lazy[rt]+=C;
sum[rt]+=(r-l+)*C;
maxx[rt]+=C;
minn[rt]+=C;
return;
}
int mid=(l+r)>>;
pushdown(l,r,rt);
if(L<=mid)update(L,R,C,l,mid,rt<<);
if(R>mid)update(L,R,C,mid+,r,rt<<|);
pushup(rt);
}
void Sqrt(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
if(maxx[rt]-minn[rt]==(LL)sqrt(maxx[rt])-(LL)sqrt(minn[rt])||maxx[rt]==minn[rt])
{
LL z=(LL)sqrt(maxx[rt])-maxx[rt];
sum[rt]+=z*(r-l+);
maxx[rt]+=z,minn[rt]+=z,lazy[rt]+=z;
return;
}
}
int mid=(l+r)>>;
pushdown(l,r,rt);
if(L<=mid)Sqrt(L,R,l,mid,rt<<);
if(R>mid)Sqrt(L,R,mid+,r,rt<<|);
pushup(rt);
}
LL query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
return sum[rt];
int mid=(l+r)>>;
LL ans=;
pushdown(l,r,rt);
if(L<=mid)ans+=query(L,R,l,mid,rt<<);
if(R>mid)ans+=query(L,R,mid+,r,rt<<|);
pushup(rt);
return ans;
}
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
build(,n,);
for(int i=;i<m;i++)
{
int op,l,r;
LL x;
scanf("%d%d%d",&op,&l,&r);
if(op==)
{
scanf("%lld",&x);
update(l,r,x,,n,);
}
else if(op==)
{
Sqrt(l,r,,n,);
}
else if(op==)
{
printf("%lld\n",query(l,r,,n,));
}
}
}
return ;
}
/*
1
5 10
1 2 3 4 5
1 1 3 10
2 1 3
2 1 3
2 1 3
2 1 3
3 1 3
*/

HDU 5828 Rikka with Sequence(线段树区间加开根求和)的更多相关文章

  1. hdu 5828 Rikka with Sequence 线段树

    Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...

  2. HDU 5828 Rikka with Sequence (线段树+剪枝优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...

  3. 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence

    // 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence // 题意:三种操作,1增加值,2开根,3求和 // 思路:这题与HDU 4027 和HDU 5634 ...

  4. 2016暑假多校联合---Rikka with Sequence (线段树)

    2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...

  5. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  6. HDU.1689 Just a Hook (线段树 区间替换 区间总和)

    HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...

  7. 【CF52C】Circular RMQ(线段树区间加减,区间最值)

    给定一个循环数组a0, a1, a2, …, an-1,现在对他们有两个操作: Inc(le, ri, v):表示区间[le, ri]范围的数值增加v Rmq(le, ri):表示询问区间[le, r ...

  8. Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间取摸

    D. The Child and Sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest ...

  9. HDU 1698 Just a Hook(线段树 区间替换)

    Just a Hook [题目链接]Just a Hook [题目类型]线段树 区间替换 &题解: 线段树 区间替换 和区间求和 模板题 只不过不需要查询 题里只问了全部区间的和,所以seg[ ...

随机推荐

  1. centos 7 下 nginx 1.10.3 编译安装的方法

    安装所需环境 Nginx 是 C语言 开发,建议在 Linux 上运行,当然,也可以安装 Windows 版本,本篇则使用 CentOS 7 作为安装环境. 一. gcc 安装安装 nginx 需要先 ...

  2. zombodb 配置设置

    主要是关于es 集群地址以及分片,复制副本的配置,配置主要在postgresql.conf,当然我们可以在函数中指定 postgresql.conf 级别的配置 es 配置 格式 zdb.defaul ...

  3. centos7 下yum源安装nginx

    简单粗暴: .rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noar ...

  4. 学习vue容易忽视的细节

    1.对于自定义标签名(组件名称),Vue.js 不强制要求遵循 W3C 规则 (小写,并且包含一个短杠),尽管遵循这个规则比较好.HTML 特性是不区分大小写的.所以,当使用的不是字符串模板,came ...

  5. oracle批量删除某个用户下的所有表

    打开sql developer,输入如下语句,把USERNAME替换为需要删除的的用户名 然后把查询出来的结果复制出来执行一遍就行了. SELECT 'DROP table '||table_name ...

  6. [UE4]Dynamic Entry Box

    Dynamic Entry Box:条目创建容器 一个特殊的容器,能够自动创建条目,在可变数量条目的时候,但是又不值得创建一个ListView或者Tile View. 注意: Dynamic Entr ...

  7. js基础系列之【原型和原型链】

    声明:形成本文的出发点仅仅是个人总结记录,避免遗忘,并非详实的教程:文中引用了经过个人加工的其它作者的内容,并非原创.学海无涯 引入问题 一般我们是这样写的: (需求驱动技术,疑问驱动进步) // 构 ...

  8. 配置iis支持json解析,配置ssi

    配置json解析: 添加mime:*.json  类型 text/json 安装iis应用程序开发中的asp功能 添加处理程序映射: 添加脚本映射 请求路径:*.json 可执行文件:C:\Windo ...

  9. Vue 双向数据绑定、事件介绍以及ref获取dom节点

    vue是一个MVVM的框架 M model V view MVVM  model改变会影响视图view,view改变会影响model 双向数据绑定必须在表单里面使用 //我发现在谷歌浏览器翻译后的网页 ...

  10. Angularjs启动入口, splash画面,与加快启动的技巧

    Angularjs启动入口, splash画面,与加快启动的技巧 Angularjs启动入口 * 自动响应DOMContentLoaded event * 从ngApp指定的入口启动: 在angula ...