HDU 5828 Rikka with Sequence(线段树区间加开根求和)
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(线段树区间加开根求和)的更多相关文章
- hdu 5828 Rikka with Sequence 线段树
Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...
- HDU 5828 Rikka with Sequence (线段树+剪枝优化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...
- 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence
// 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence // 题意:三种操作,1增加值,2开根,3求和 // 思路:这题与HDU 4027 和HDU 5634 ...
- 2016暑假多校联合---Rikka with Sequence (线段树)
2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...
- HDU.1556 Color the ball (线段树 区间更新 单点查询)
HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...
- HDU.1689 Just a Hook (线段树 区间替换 区间总和)
HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...
- 【CF52C】Circular RMQ(线段树区间加减,区间最值)
给定一个循环数组a0, a1, a2, …, an-1,现在对他们有两个操作: Inc(le, ri, v):表示区间[le, ri]范围的数值增加v Rmq(le, ri):表示询问区间[le, r ...
- 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 ...
- HDU 1698 Just a Hook(线段树 区间替换)
Just a Hook [题目链接]Just a Hook [题目类型]线段树 区间替换 &题解: 线段树 区间替换 和区间求和 模板题 只不过不需要查询 题里只问了全部区间的和,所以seg[ ...
随机推荐
- win10企业版2016长期服务版本激活
右键左下角Windows开始图标 ——> 单击 命令提示符(管理员)A 粘贴如下代码到dos窗口: slmgr /ipk DCPHK-NFMTC-H88MJ-PFHPY-QJ4BJ slm ...
- 备忘:EBS参考链接
帮助手册查阅网址http://docs.oracle.com/cd/V46499_01/current/html/docset.html 官方 http://www.oracleappshub.co ...
- 一篇讲解如何调试pg 扩展的文章
以下链接这片关于pg 扩展调试的文章挺不错,记录下 http://big-elephants.com/2015-10/writing-postgres-extensions-part-iii/ ...
- jQeury 批量删除
/*批量删除*/ function datadel(){ var ids = new Array(); $("input[name='batch']:checked").each( ...
- IIS 负载均衡
在大型Web应用系统中,由于请求的数据量过大以及并发的因素,导致Web系统会出现宕机的现象,解决这一类问题的方法我个人觉得主要在以下几个方面: 1.IIS 负载均衡. 2.数据库 负载均衡. 3.系统 ...
- mongodb集群配置副本集
测试环境 操作系统:CentOS 7.2 最小化安装 主服务器IP地址:192.168.197.21 mongo01 从服务器IP地址:192.168.197.22 mongo02 从服务器IP地址: ...
- 域名到站点的负载均衡技术一览(主要是探讨一台Nginx抵御大并发的解决方案)(转)https://www.cnblogs.com/EasonJim/p/7823410.html
一.问题域 Nginx.LVS.Keepalived.F5.DNS轮询,往往讨论的是接入层的这样几个问题: 1)可用性:任何一台机器挂了,服务受不受影响 2)扩展性:能否通过增加机器,扩充系统的性能 ...
- JDK / JRE zip
Server JRE与JRE的区别: Server JRE一般用于服务器上安装,只有64bit版本,不会安装浏览器插件.自动更新,有监视工具.没有Java Fx和其他开发工具:有安装程序,只是一压缩目 ...
- HTTP响应过程
完整的一次 HTTP 请求响应过程(一)http://mp.weixin.qq.com/s?__biz=MzUzMTA2NTU2Ng==&mid=2247484648&idx=1&am ...
- WampServer的下载方法
http://www.wampserver.com/ 无法访问 报网络连接错误 2019.01.13 最近要用到Windows+apache+mysql+php,为了追求更快的实现速度和更高的稳定性, ...