题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828

给你n个数,m个操作,操作k,l,r,

k=1时 区间[l,r]每个数加x;

k=2时,区间[l,r]每个数开平方;

k=3时,求区间[l,r]的和。

开方的操作执行的次数,并不多到所以最后会出现很多相同的数,我们可以把相同的数统一减去一个数即可,但是数据中如果存在2 3 2 3 2 3 2 3,有10w次+6,然后开方,这样的话,时间复杂度也是很高的;所以我们可以看到,只要两个数相差一,开方后还相差一,那么我们可以减去一个数完成;

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<math.h>
using namespace std;
#define N 100005
#define met(a, b) memset(a, b, sizeof(a))
#define mod 1000000007
typedef long long LL;
#define Lson r<<1
#define Rson r<<1|1 struct Tree
{
int L, R;
LL lazy, Min, Max, sum;
int mid() { return (L+R)/; }
int len() { return (R-L+); }
}a[N<<]; void BuildTree(int r, int L, int R)
{
a[r].L = L; a[r].R = R; a[r].lazy = ; if(a[r].L == a[r].R)
{
scanf("%I64d", &a[r].sum);
a[r].Max = a[r].Min = a[r].sum;
return ;
} BuildTree(Lson, L, a[r].mid());
BuildTree(Rson, a[r].mid()+, R); a[r].sum = a[Lson].sum + a[Rson].sum;
a[r].Max = max(a[Lson].Max, a[Rson].Max);
a[r].Min = min(a[Lson].Min, a[Rson].Min);
} void Down(int r)
{
a[Lson].lazy += a[r].lazy; a[Rson].lazy += a[r].lazy; a[Lson].sum += a[Lson].len()*a[r].lazy;
a[Rson].sum += a[Rson].len()*a[r].lazy; a[Lson].Max += a[r].lazy; a[Rson].Max += a[r].lazy;
a[Lson].Min += a[r].lazy; a[Rson].Min += a[r].lazy; a[r].lazy = ;
} void Up(int r)
{
a[r].sum = a[Lson].sum + a[Rson].sum; a[r].Max = max(a[Lson].Max, a[Rson].Max);
a[r].Min = min(a[Lson].Min, a[Rson].Min);
} void Update1(int r, int L, int R, LL num)
{
a[r].sum += (R-L+) * num;
if(a[r].L == L && a[r].R == R)
{
a[r].Max += num;
a[r].Min += num;
a[r].lazy += num;
return ;
} Down(r);///往下传递Lazy; if(R <= a[r].mid())
Update1(Lson, L, R, num);
else if(L > a[r].mid())
Update1(Rson, L, R, num);
else
{
Update1(Lson, L, a[r].mid(), num);
Update1(Rson, a[r].mid()+, R, num);
} Up(r);///往上传递Lazy;
}
void Update2(int r, int L, int R)
{
if(a[r].L == L && a[r].R == R)
{
if(a[r].Min == a[r].Max)///当区间内所有的数都相等时,相当于区间内所有数都减去同一个数;
{
LL num = (LL)sqrt(a[r].Max) - a[r].Max;
a[r].sum += a[r].len() * num;
a[r].lazy += num;
a[r].Max += num;
a[r].Min += num; return;
}
else if(a[r].Min + == a[r].Max)///当数之间相差<=1的时候并且开方之后还是相差1的话,那么他们可以通过加一个数得到;
{
LL num1 = (LL)sqrt(a[r].Max);
LL num2 = (LL)sqrt(a[r].Min);
if(num1 == num2+)
{
LL num = num1 - a[r].Max;
a[r].sum += a[r].len() * num;
a[r].lazy += num;
a[r].Max += num;
a[r].Min += num;
return;
}
}
} Down(r); if(R <= a[r].mid())
Update2(Lson, L, R);
else if(L > a[r].mid())
Update2(Rson, L, R);
else
{
Update2(Lson, L, a[r].mid());
Update2(Rson, a[r].mid()+, R);
} Up(r);
}
LL Query(int r, int L, int R)
{
if(L == a[r].L && R == a[r].R)
{
return a[r].sum;
}
Down(r);
if(R <= a[r].mid())
return Query(Lson, L, R);
else if(L > a[r].mid())
return Query(Rson, L, R);
else
{
LL ans1 = Query(Lson, L, a[r].mid());
LL ans2 = Query(Rson, a[r].mid()+, R);
return ans1 + ans2;
}
} int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n, m, op, L, R; LL num; scanf("%d %d", &n, &m); BuildTree(, , n); while(m--)
{
scanf("%d", &op);
if(op == )
{
scanf("%d %d %I64d", &L, &R, &num);
Update1(, L, R, num);
}
else if(op == )
{
scanf("%d %d", &L, &R);
Update2(, L, R);
}
else
{
scanf("%d %d", &L, &R);
LL ans = Query(, L, R);
printf("%I64d\n", ans);
}
}
}
return ;
}

Rikka with Sequence---hdu5828(区间更新与查找 线段树)的更多相关文章

  1. SRM12 T2夏令营(分治优化DP+主席树 (已更新NKlogN)/ 线段树优化DP)

     先写出朴素的DP方程f[i][j]=f[k][j-1]+h[k+1][i] {k<i}(h表示[k+1,j]有几个不同的数)  显然时间空间复杂度都无法承受   仔细想想可以发现对于一个点 i ...

  2. P2075 [NOIP2012T5]借教室 区间更新+二分查找

    P2075 [NOIP2012T5]借教室 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 noip2012-tg 描述 在大学期间,经常需要租借教室.大到院 ...

  3. HDU-4614 Vases and Flowers(线段树区间更新+二分查找)

    http://acm.hdu.edu.cn/showproblem.php?pid=4614 Time Limit: 4000/2000 MS (Java/Others)    Memory Limi ...

  4. HDU 1754 - I Hate It & UVA 12299 - RMQ with Shifts - [单点/区间修改、区间查询线段树]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 Time Limit: 9000/3000 MS (Java/Others) Memory Li ...

  5. [NOI2016]区间 题解(决策单调性+线段树优化)

    4653: [Noi2016]区间 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1593  Solved: 869[Submit][Status][ ...

  6. codedecision P1112 区间连续段 题解 线段树

    题目描述:https://www.cnblogs.com/problems/p/P1112.html 题目链接:http://codedecision.com/problem/1112 线段树区间操作 ...

  7. luogu P1712 [NOI2016]区间 贪心 尺取法 线段树 二分

    LINK:区间 没想到尺取法. 先说暴力 可以发现答案一定可以转换到端点处 所以在每个端点从小到大扫描线段就能得到答案 复杂度\(n\cdot m\) 再说我的做法 想到了二分 可以进行二分答案 从左 ...

  8. HihoCoder1070 区间最小值(简单线段树)

    个测试点(输入文件)有且仅有一组测试数据. 每组测试数据的第1行为一个整数N,意义如前文所述. 每组测试数据的第2行为N个整数,分别描述每种商品的重量,其中第i个整数表示标号为i的商品的重量weigh ...

  9. AcWing:246. 区间最大公约数(线段树 + 增量数组(树状数组) + 差分序列)

    给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1.“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d. 2.“Q l r”,表示询问 A[l],A[l ...

随机推荐

  1. Java - Calendar类的使用

    今天在写代码时需要用到时间相关的类,一开始,数据库中存的数据类型是timestamp的,所以在Java中就使用了 Timestamp类型,但当调用Timestamp类型的方法时发现,它的很多方法都是d ...

  2. HTML 注释

    "<!-- xxx -->" 用于在 HTML 中插入注释,注释是用来给开发人员看的,浏览器不会显示注释内容 <!DOCTYPE HTML> <htm ...

  3. React Native(四)——顶部以及底部导航栏实现方式

    效果图: 一步一步慢慢来: 其实刚入手做app的时候,就应该做出简单的顶部以及底部导航栏.无奈又在忙其他事情,导致这些现在才整理出来. 1.顶部导航栏:react-native-scrollable- ...

  4. lua元表(metatable)和元方法(metamethod)

    (一) 元表概念: 引言:Lua中的每个值都有一套预定义的操作集合,如数字相加等.但无法将两个table相加,此时可通过元表修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定操作. 访问机制 ...

  5. javascript/css压缩工具---yuicompressor使用方法

    1. 下载 地址:https://github.com/yui/yuicompressor/downloads 2. 安装 yuicompressor是由java写成的一组jar文件,需要jdk环境支 ...

  6. /etc/fstab文件损坏的补救措施

    最近乱搞,把/etc/fstab弄坏了,导致无法进入图形界面,而且所有文件都是只读的(简直郁闷到底啊),查了好多资料什么的终于弄好了,也走了不少弯路 恩,我不喜欢扯太多东西,这个是补救的帖子,还是希望 ...

  7. hive异常:创建MySQL时Specified key was too long; max key length is 1000 bytes

    2015-11-13 14:44:44,681 ERROR [main]: DataNucleus.Datastore (Log4JLogger.java:error(115)) - An excep ...

  8. thinkphp 控制器unset删除对象变量失败。。

    今儿开发过程中发现 tp是unset 变量失败..具体代码 foreach( $this->menu as $k => $v){ if(0 == $v['flag']) unset($th ...

  9. UVA 10120 - Gift?!(搜索+规律)

     Problem D. Gift?!  The Problem There is a beautiful river in a small village. N rocks are arranged ...

  10. js 的空值判断程序

    function empty(v){ switch (typeof v){ case 'undefined' : return true; case 'string' : if($.trim(v).l ...