题目链接: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. 【代码审计】iZhanCMS_v2.1 前台IndexController.php页面存在SQL注入 漏洞分析

      0x00 环境准备 iZhanCMS官网:http://www.izhancms.com 网站源码版本:爱站CMS(zend6.0) V2.1 程序源码下载:http://www.izhancms ...

  2. 绕过D盾的一句话

    一个很简单的一个技巧,作个笔记,可以绕过D盾检测. 新建test1.php <?php eval($_POST[g]); ?> 新建test2.php <?php $a=" ...

  3. RF-For循环使用

    场景1:

  4. iOS开发-- 字符串分割、拼接

    ---------------------字符串分割实例---------------------NSString * ptr = @"I am a man"; //将字符串整体作 ...

  5. [转]linux下释放文件内存

    在Linux系统下,我们一般不需要去释放内存,因为系统已经将内存管理的很好.但是凡事也有例外,有的时候内存会被缓存占用掉,导致系统使用SWAP空间影响性能,此时就需要执行释放内存(清理缓存)的操作了. ...

  6. HTML 注释

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

  7. C++多线程编程简单实例

    C++本身并没有提供任何多线程机制,但是在windows下,我们可以调用SDK win32 api来编写多线程的程序,下面就此简单的讲一下: 创建线程的函数 HANDLE CreateThread( ...

  8. 基础知识《十二》一篇文章理解Cookie和Session

    理解Cookie和Session机制 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定 ...

  9. [Win32]一个调试器的实现(五)调试符号

    一个调试器应该可以跟踪被调试程序执行到了什么地方,显示下一条将要执行的语句,显示各个变量的值,设置断点,进行单步执行等等,这些功能都需要一个基础设施的支持,那就是调试符号. 什么是调试符号 我们知道, ...

  10. 解决一起web 页面被劫持的案例

    现象 江西客户手机端连接wifi打开URL,页面上显示淘宝店铺广告,使用手机移动网络打开正常,其他地区正常. 二. 处理过程 初步分析:3g.club项目使用了CDN,目前只有江西异常,其他地区无异常 ...