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. [Java] 例外處裡 try/catch & throws

    public class CheckException { public static void main(String[] args) { File file = new File("xx ...

  2. extjs_10_自己定义combotree组件

    1.项目截图 2.treedata.json { text : "root", expanded : true, expandable : true, children : [{ ...

  3. py-day3-3 python 函数的作用域

    def test1(): print('in the test1') def test(): print('in the test') return test1 print(test) res = t ...

  4. Java面试题 OOAD & UML+XML+SQL+JDBC & Hibernate

    二.OOA/D 与UML 部分:(共6 题:基础2 道,中等难度4 道) 96.UML 是什么?常用的几种图?[基础] 答:UML 是标准建模语言:常用图包括:用例图,静态图(包括类图.对象图和包图) ...

  5. redis 4.x 安装哨兵模式 sentinel

    1.下载 http://download.redis.io/releases/redis-4.0.11.tar.gz 2.解压 tar zxvf redis-4.0.11.tar.gz 3.安装 cd ...

  6. JAVA web端JS下载excel文件

    JSP代码如下: JSP端引入jquery.easyui.min.js库: <script type="text/javascript" src="<c:ur ...

  7. [UE4]Named Slot

    用户创建的UI成为其他UI的子控件的时候,默认情况下是不能拥有子控件的,给UI添加一个Named Slot,这个UI就可以拥有子控件 一.创建一个名为testNameSlot的UI,添加3个Named ...

  8. 4、Zookeeper简单介绍

    一.分布式协调技术 在给大家介绍ZooKeeper之前先来给大家介绍一种技术——分布式协调技术.那么什么是分布式协调技术?那么我来告诉大家,其实分布式协调技术 主要用来解决分布式环境当中多个进程之间的 ...

  9. ubuntu下安装owncloud提示没有zip模块时

    wget http://pecl.php.net/get/zip-1.13.5.tgztar -zvxf zip-1.13.5.tgzcd zip-1.13.5phpize ./configure m ...

  10. inception 自动化sql审核

    ##概念: Inception是一款自动化运维的利器,有别与现在各个公司使用的方式,使用Inception,将会给DBA带来最大的便利性,将DBA从繁冗的工作中解放出来,做一些更多的自动化工作,或者从 ...