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[ ...
随机推荐
- ios-项目启动页面
项目运行启动页面: 点工程项目targets-(或Images.xcasets)-LaunchImage(iphone四种规格图片:320*480/350*568/640*960/640*1136)将 ...
- NumPy 基础用法
NumPy 是高性能科学计算和数据分析的基础包. 它是 pandas 等其他各种工具的基础. 主要功能: ndarray 一个多维数组结构, 高效且节省空间 无需循环对整组数据进行快速运算的数学函数 ...
- ScriptManager 发送错误到客户端
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...
- jQuery 点击后退(返回)执行函数
<html> <head> <meta charset="UTF-8"> <meta name="viewport" ...
- JS 格式化日期时间
方法一: // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1 ...
- HTML5操作麦克风获取音频数据(WAV)的一些基础技能
基于HTML5的新特性,操作其实思路很简单. 首先通过navigator获取设备,然后通过设备监听语音数据,进行原始数据采集. 相关的案例比较多,最典型的就是链接:https://developer. ...
- linux 6.5上创建新用户后,不能登陆?
linux 6.5上创建新用户后,不能登陆? 使用root账户登陆却可以! [root@ log]# useradd mtdk[root@ log]# echo 123abc |passwd --st ...
- pj2--图书管理系统
这一次做得是图书管理系统. 下面是功能框图 下面是流程图 实际在做这个项目的时候根据相应的实际情况对功能流程等等做了一些小小的改变. 下面是一些值得记一笔的地方. 1.借用系统自带的导航控件(Bind ...
- Python之Eric安装注意事项
处理该问题: http://www.knowsky.com/950133.html 注意缺乏的是qscintilla 双击install.py进行安装
- crossdomain.xml配置不当的利用和解决办法
00x1: 今天在无聊的日站中发现了一个flash小站,点进crossdomain.xml一看,震惊 本屌看到这个*就发觉事情不对 百度一下,这是一个老洞,配置不当能引起各种问题就算能远程加载恶意的s ...