title: hdu-4027线段树练习

date: 2018-10-10 18:07:11

tags:

  • acm
  • 算法
  • 刷题

    categories:
  • ACM-线段树

概述

这道线段树的题可以说是我这一段时间复习线段树后第一次认认真真的做的第一道线段树的题了吧,,,,

然后,,,看似很简单的题翻车了,,,,QAQ

题意和分析

题意大概就是给你一些数,,然后对[l , r]这个区间里的所有数进行开平方根运算,,,其中还有一些询问[l , r]的区间和,,,

看到一排数列的区间和还有更新询问操作的题型铁定是要用线段树来维护这个数列了,,,

一开始我想着结点保存两个区间和,,一个是现在未更新的区间和,,另一个是每个开方后的区间和,,,然后用lazy来延迟更新,,,然后貌似在更新时这样会少更新,,,最后的答案肯定就不对了,,

最后,,,坑了两个多小时的我还是去找别人的做法了,,,

这道题首先一点就是即使数字很大,,,但是 \(2^{63} - 1\) 也就最多开8次平方根,,,而且开到1时再开平方根还是1,,,,

所以再开到区间所有数都为1时就不再对这个区间更新,,,也就是当 node[rt].sum == node[rt].r - node[rt].l + 1 时就返回上一层,,,这样就减小了更新时的操作,,,

最终的代码,,,

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int n, q;
ll a[maxn];
struct tree
{
int l;
int r;
ll sum;
}node[maxn << 2]; void pushup(int rt)
{
node[rt].sum = node[rt << 1].sum + node[rt << 1 | 1].sum;
} void build(int rt , int l , int r)
{
node[rt].l = l;
node[rt].r = r; if (l == r)
{
node[rt].sum = a[l];
return; //要记得return,,,最近写这个总是忘记写
} int mid = (l + r) >> 1; build(rt << 1 , l , mid);
build(rt << 1 | 1 , mid + 1 , r);
pushup(rt);
return;
} void update(int rt , int L , int R)
{
if (node[rt].sum == node[rt].r - node[rt].l + 1)
return; //区间全为1时返回,,,不然会tle
if (node[rt].l == node[rt].r)
{
node[rt].sum = (ll)(sqrt(node[rt].sum)); //直接开方就行了
return;
} int mid = (node[rt].l + node[rt].r) >> 1;
if (L <= mid) update(rt << 1 , L , R);
if (R > mid) update(rt << 1 | 1 , L , R);
pushup(rt);
return;
}
ll query(int rt , int L , int R)
{ if (L <= node[rt].l && node[rt].r <= R)
{
return node[rt].sum;
} int mid = (node[rt].l + node[rt].r) >> 1;
ll ans = 0;
if (L <= mid) ans += query(rt << 1 , L , R);
if (R > mid) ans += query(rt << 1 | 1 , L , R);
return ans;
} int main(int argc, char const *argv[])
{
int i = 0;
while(scanf("%d" , &n) != EOF)
{
printf("Case #%d:\n" , ++i);
for (int i = 1; i <= n; ++i)
scanf("%lld" , &a[i]); build(1 , 1 , n); scanf("%d" , &q); while(q--)
{
int t , l , r;
scanf("%d%d%d" , &t , &l , &r);
if (l > r)
swap(l , r); //l , r不一定保证 l <= r 所以要判断 if (t)
printf("%lld\n" , query(1 , l , r));
else
update(1 , l , r);
}
printf("\n"); //每组测试样例之间加空行
}
return 0;
}

总结

  • 没看出来一个数最多开方8次啊,,,
  • 还是不能仔细的读题,,,比如那个输入的l , r比如那个每一组测试样例之间加空行
  • 想的太多了,,,而且最主要的是还是想着套模板解题,,,而不是就题而选择怎么写
  • ,,,,

还是做的题太少了,,还是有点像暑假时见到线段树就套板子,,套板子,,已经好几次套板子是没用的情况了,,,而且除了入门的线段树的题,,,都不是之套板子就能出结果的,,,都要在某些地方加一些判断,,,或者对数据的处理,,,线段树只是众多工具之一啊,,不是万能的呐,,,,

(end)

动手总比只想所得到的多一些,,即使结果不尽人意呐~

hdu-4027线段树练习的更多相关文章

  1. Can you answer these queries? HDU 4027 线段树

    Can you answer these queries? HDU 4027 线段树 题意 是说有从1到编号的船,每个船都有自己战斗值,然后我方有一个秘密武器,可以使得从一段编号内的船的战斗值变为原来 ...

  2. V - Can you answer these queries? HDU - 4027 线段树 暴力

    V - Can you answer these queries? HDU - 4027 这个题目开始没什么思路,因为不知道要怎么去区间更新这个开根号. 然后稍微看了一下题解,因为每一个数开根号最多开 ...

  3. HDU 4027 <线段树,区间√>

    题目连接 题意 给出一个区间,每次把[l,r]内的值√,维护区间和. 坑: £:l会比r大,swap. £: 当f[i].sum=f[i].r-f[i].l+1;,不修改.因为保证每个数都大于等于1, ...

  4. HDU - 4027 线段树减枝

    这题太坑了...满满的都是坑点 1号坑点:给定左右区间有可能是反的...因为题目上说x,y之间,但是没有说明x,y的大小关系(害我一直RE到怀疑人生) 2号坑点:开根号的和不等于和开根号(还好避开了) ...

  5. hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  6. hdu 3974 线段树 将树弄到区间上

    Assign the task Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. hdu 3436 线段树 一顿操作

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  8. hdu 3397 线段树双标记

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  9. hdu 4578 线段树(标记处理)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others) ...

  10. hdu 4533 线段树(问题转化+)

    威威猫系列故事——晒被子 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

随机推荐

  1. Java使用UDP发送数据到InfluxDB

    最近在做压测引擎相关的开发,需要将聚合数据发送到InfluxDB保存以便实时分析和控制QPS. 下面介绍对InfluxDB的使用. 什么是InfluxDB InfluxDB是一款用Go语言编写的开源分 ...

  2. 在windows的IDEA运行Presto

    After building Presto for the first time, you can load the project into your IDE and run the server. ...

  3. 20145234黄斐《Java程序设计》第七周

    教材学习内容总结 第十二章部分 - Lambda 认识Lambda语法 Lambda去可以重复,符合DRY原则,而且Lambda表达式可读性更好,操作更简单 匿名类型最大的问题就在于其冗余的语法,la ...

  4. 学号20155311 2016-2017-2 《Java程序设计》第7周学习总结

    学号20155311 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 时间的度量 格林威治时间,简称GMT时间,由观察太阳而得来:世界时,UT:国际原子时,T ...

  5. HDU 1019 Least Common Multiple GCD

    解题报告:求多个数的最小公倍数,其实还是一样,只需要一个一个求就行了,先将答案初始化为1,然后让这个数依次跟其他的每个数进行求最小公倍数,最后求出来的就是所有的数的最小公倍数.也就是多次GCD. #i ...

  6. Java:数值-字符串转换(String转Double)

    String ss = "3.141592653"; double value = Double.valueOf(ss.toString());

  7. python 面试题3

    注:本面试题来源于网络. 1.python下多线程的限制以及多进程中传递参数的方式 python多线程有个全局解释器锁(global interpreter lock),这个锁的意思是任一时间只能有一 ...

  8. solr配置中文分词器——(十二)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAqcAAAGzCAIAAACdKClDAAAgAElEQVR4nOydd5gUxdbGx5xASZKXLB

  9. 修复TortoiseGit文件夹和文件图标不显示问题的多种解决办法以及重启之后TortoiseGit图标注册表又不见了的解决办法

    一 首先进行第一种尝试 打开 regedit.exe ,准备修改注册表 找到 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\ ...

  10. Gradle教程链接

    Gradle教程:https://www.yiibai.com/gradle/ https://www.cnblogs.com/wxishang1991/p/5532006.html