博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU - 4027 Can you answer these queries?(线段树)
阅读量:5109 次
发布时间:2019-06-13

本文共 3086 字,大约阅读时间需要 10 分钟。

 

 

给定一个长度为n的序列,m次操作。

每次操作

  可以将一个区间内的所有数字变为它的根号。

  可以查询一个区间内所有元素的和。

 

 

 

 

线段树的初级应用。

如果把一个区间内的元素都改为它的根号的话,是需要每个数字都进行修改的。这样就会超时。

一个优化就是区间修改的当区间时,若区间长度等于区间和,那这个区间里的所有元素都不用修改了。

而题目中区间里的元素之和最大是 2^63,时间完全够用。

 

#include 
#include
#include
#include
using namespace std;#define maxn 100000 + 1000#define LL long long#define in_int(x) int x; scanf("%d", &x);struct Sect{ int l, r, flag; LL sum; Sect() : flag(0) {}}t[4*maxn];LL n, a[4*maxn];void build(int id, int l, int r){ if (l == r) { t[id].sum = a[l]; t[id].l = l, t[id].r = r; return; } int mid = (l+r) >> 1; build(id*2, l, mid); build(id*2+1, mid+1, r); t[id].sum = t[id*2].sum + t[id*2+1].sum; t[id].l = t[id*2].l, t[id].r = t[id*2+1].r;}//void update(int id, int x, int val)//{// if(t[id].l == t[id].r)// {// if (t[id].l == x) t[id].sum += val;// return;// }// int mid = (t[id].l+t[id].r) >> 1;// if (x <= mid) update(id*2, x, val);// else update(id*2+1, x, val);// t[id].sum = t[id*2].sum + t[id*2+1].sum;//}//void markdown(int id)//{// t[id].flag = 0;// t[id].sum = (int)sqrt(t[id].sum);// if (t[id*2].flag) markdown(id*2);// t[id*2].flag = 1;// if (t[id*2+1].flag) markdown(id*2+1);// t[id*2+1].flag = 1;//}LL query(int id, int l, int r){ //if(t[id].flag) markdown(id); if (t[id].l >= l && t[id].r <= r) return t[id].sum; int mid = (t[id].l + t[id].r) >> 1; if (r <= mid) return query(id*2, l, r); else if (l > mid) return query(id*2+1, l, r); else return query(id*2, l, mid) + query(id*2+1, mid+1, r);}void change(int id, int l, int r){ if (t[id].l == t[id].r) { t[id].sum = sqrt(t[id].sum); return; } if (t[id].r - t[id].l + 1 == t[id].sum) return; int mid = (t[id].l + t[id].r) >> 1; if (r <= mid) change(id*2, l, r); else if (l > mid) change(id*2+1, l, r); else { change(id*2, l, mid); change(id*2+1, mid+1, r); } t[id].sum = t[id*2].sum + t[id*2+1].sum;}int main(){ int n, ca = 0; while(scanf("%lld", &n) != EOF) { for (int i = 1; i <= n; i++) scanf("%lld", &a[i]); build(1, 1, n); printf("Case #%d:\n", ++ca); in_int(m); for (int i = 1; i <= m; i++) { in_int(x); in_int(l); in_int(r); if (l > r) swap(l, r); if (x) printf("%lld\n", query(1, l, r)); else change(1, l, r); } printf("\n"); }}

 

转载于:https://www.cnblogs.com/ruthank/p/9458659.html

你可能感兴趣的文章
可选参数的函数还可以这样设计!
查看>>
[你必须知道的.NET]第二十一回:认识全面的null
查看>>
Java语言概述
查看>>
关于BOM知识的整理
查看>>
使用word发布博客
查看>>
面向对象的小demo
查看>>
微服务之初了解(一)
查看>>
GDOI DAY1游记
查看>>
收集WebDriver的执行命令和参数信息
查看>>
数据结构与算法(三)-线性表之静态链表
查看>>
mac下的mysql报错:ERROR 1045(28000)和ERROR 2002 (HY000)的解决办法
查看>>
MyBaits动态sql语句
查看>>
HDU4405(期望DP)
查看>>
拉格朗日乘子法 那些年学过的高数
查看>>
vs code 的便捷使用
查看>>
Spring MVC @ResponseBody返回中文字符串乱码问题
查看>>
用户空间与内核空间,进程上下文与中断上下文[总结]
查看>>
JS 中的跨域请求
查看>>
JAVA开发环境搭建
查看>>
mysql基础语句
查看>>