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. js生成接口请求参数签名加密

    js生成接口请求参数签名加密 定义规则:将所有参数字段按首字母排序, 拼接成key1 = value1 & key2 = value2的格式,再在末尾拼接上key = appSecret, 再 ...

  2. HDU 2087 剪花布条 (KMP 不允许重叠的匹配)

    题目链接 Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Inp ...

  3. git之合并分支(git merge)------(三)

    最近几天写小demo,总是自己拉取他人的代码,然后创建分支,在自己的分支上进行修改,然后提交到自己的分支,具体的这一步,我就不多讲了,因为在我的博客“工作中常用的Git操作”中有详细的介绍,今天主要讲 ...

  4. python3学习笔记.4.turtle绘图

    先放上参考 https://docs.python.org/3/library/turtle.html //********************************************** ...

  5. ActiveMQ与SpringMVC整合实现发送PTP和订阅发布消息功能

    实现一个基于SpringMVC+JMS+ActiveMQ+Tomcat+JDK1.8+IDEA工具 ,Spring4.1.0和ActiveMQ5.15整合的实例,实现PTP和订阅/发布两种消息模型 一 ...

  6. C# WebClient进行FTP服务上传文件和下载文件

    定义WebClient使用的操作类: 操作类名称WebUpDown WebClient上传文件至Ftp服务: //// <summary> /// WebClient上传文件至Ftp服务 ...

  7. 自动化测试Robotium获取当前页面的activity,用于判断是否进入这个页面

    一.启动app 二.进入命令行窗口输入 adb shell “dumpsys activity activities | grep mFocusedActivity” 三.断言方法 assertTru ...

  8. 002_安装第三方APP好的站点及解除安全与隐私限制

    一.解除安全与隐私限制的任何来源. http://bbs.feng.com/read-htm-tid-10714286.html 接下来,我们就打开终端,然后输入以下命令:   sudo spctl ...

  9. [ python ] 学习目录大纲

    简易博客[html+css]练习 MySQL 练习题及答案 MySQL视图.触发器.函数.存储过程 MySQL 操作总结 Day41 - 异步IO.协程 Day39/40 - 线程的操作 Day36/ ...

  10. Java KeyStore 用命令生成keystore文件自己生成证书,简介

    1.生成keyStore文件 在命令行下执行以下命令: Shell代码 收藏代码 keytool -genkey -validity 36000 -alias www.zlex.org -keyalg ...