原题链接

题意

  • 初始有一长度为n,全为0的序列

  • 每次我们可以对这个序列进行三种操作:

    • 1.将某个位置的数加上d

    • 2.输出某个区间的和

    • 3.将某个区间内每个数字变为与其最接近的斐波那契数,如果有两个最相近的数,则取更小的那个。

思路

  • 首先对于寻找最近的斐波那契数,我们可以预处理一个90+大小的数组来保存斐波那契数列的前90项,此时范围其实已经要覆盖long long了,完全够用,可以用lower_bound来查询

  • 然后就是这个区间和可以用线段树保存,对于区间的3操作,肯定是不能一个一个去操作的,所以我们可以想到在操作前我们就保存好这个区间的“斐波那契和”。

  • 这样的话,对于每次单点修改操作,我们都要更新一遍线段树路径上的区间和与“斐波那契和”,可以发现,题目中没有区间加和修改的操作,正是我们这种方法得以实行的原因——每次只需要更新一条路上的数据。然后我们使用lazy标记确保3操作的时间复杂度即可。

AC代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; struct ab
{
long long v;
long long fv;
bool fl;
} aa[400005];
int n, m, co = 0; long long fb[1005]; long long abss(long long a)
{
if (a < 0)
{
a = -a;
}
return a;
} void build(int o, int l, int r)
{
aa[o].fl = false;
if (l == r)
{
aa[o].v = 0;
aa[o].fv = 1;
return;
}
int mid = (l + r) >> 1;
build(o << 1, l, mid);
build(o << 1 | 1, mid + 1, r);
aa[o].v = aa[o << 1].v + aa[o << 1 | 1].v;
aa[o].fv = aa[o << 1].fv + aa[o << 1 | 1].fv;
} void pd(int o)
{
if (aa[o].fl)
{
aa[o].fl = false;
aa[o << 1].v = aa[o << 1].fv;
aa[o << 1].fl = true;
aa[o << 1 | 1].v = aa[o << 1 | 1].fv;
aa[o << 1 | 1].fl = true;
}
} void update(int o, int l, int r, int k, long long x)
{
if (l == r)
{
aa[o].v += x;
int ll = lower_bound(fb, fb + 91, aa[o].v) - fb;
if (!ll)
{
aa[o].fv = 1;
}
else if (abss(fb[ll] - aa[o].v) < abss(fb[ll - 1] - aa[o].v))
{
aa[o].fv = fb[ll];
}
else
{
aa[o].fv = fb[ll - 1];
}
return;
}
pd(o);
int mid = (l + r) >> 1;
if (l <= k && mid >= k)
{
update(o << 1, l, mid, k, x);
}
if (mid < k && r >= k)
{
update(o << 1 | 1, mid + 1, r, k, x);
}
aa[o].v = aa[o << 1].v + aa[o << 1 | 1].v;
aa[o].fv = aa[o << 1].fv + aa[o << 1 | 1].fv;
} void change(int o, int l, int r, int x, int y)
{
if (x <= l && y >= r)
{
aa[o].fl = true;
aa[o].v = aa[o].fv;
return;
}
pd(o);
int mid = (l + r) >> 1;
if (x <= mid)
{
change(o << 1, l, mid, x, y);
}
if (y > mid)
{
change(o << 1 | 1, mid + 1, r, x, y);
}
aa[o].v = aa[o << 1].v + aa[o << 1 | 1].v;
aa[o].fv = aa[o << 1].fv + aa[o << 1 | 1].fv;
} long long qu(int o, int l, int r, int x, int y)
{
if (l >= x && r <= y)
{
return aa[o].v;
}
pd(o);
int mid = (l + r) >> 1;
long long ans1 = 0, ans2 = 0;
if (x <= mid)
{
ans1 = qu(o << 1, l, mid, x, y);
}
if (y > mid)
{
ans2 = qu(o << 1 | 1, mid + 1, r, x, y);
}
return ans1 + ans2;
} int main()
{
fb[1] = fb[0] = 1;
for (int i = 2; i <= 90; ++i)
{
fb[i] = fb[i - 2] + fb[i - 1];
}
while (scanf("%d%d", &n, &m) == 2)
{
build(1, 1, n);
for (int i = 1; i <= m; ++i)
{
int q, l, r;
scanf("%d", &q);
if (q == 1)
{
int t;
long long xx;
scanf("%d%lld", &t, &xx);
update(1, 1, n, t, xx);
}
else if (q == 2)
{
scanf("%d%d", &l, &r);
printf("%lld\n", qu(1, 1, n, l, r));
}
else
{
scanf("%d%d", &l, &r);
change(1, 1, n, l, r);
}
}
}
return 0;
}

HDU 4893 线段树延迟标记的更多相关文章

  1. HDU 3468:A Simple Problem with Integers(线段树+延迟标记)

    A Simple Problem with Integers Case Time Limit: 2000MS Description You have N integers, A1, A2, ... ...

  2. hdu 5023 线段树延迟更新+状态压缩

    /* 线段树延迟更新+状态压缩 */ #include<stdio.h> #define N 1100000 struct node { int x,y,yanchi,sum; }a[N* ...

  3. HDU 4893 线段树的 点更新 区间求和

    Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  4. HDU 4893 线段树裸题

    Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  5. HDU 4893 线段树

    比赛时太大意,斐波拉契数列开小了. 题目大意:1个序列,3种操作,改变序列某个数大小,将序列中连续的一段每个数都变成其最近的斐波拉契数,以及查询序列中某一段的数之和. 解题思路:维护add[]数组表示 ...

  6. Tree(树链剖分+线段树延迟标记)

    Tree http://poj.org/problem?id=3237 Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 12 ...

  7. codevs 1690 开关灯 线段树+延迟标记

    1690 开关灯  时间限制: 1 s  空间限制: 128000 KB   题目描述 Description YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这 ...

  8. HDU4893--Wow! Such Sequence! (线段树 延迟标记)

    Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  9. Jiu Yuan Wants to Eat(树链剖分+线段树延迟标记)

    Jiu Yuan Wants to Eat https://nanti.jisuanke.com/t/31714 You ye Jiu yuan is the daughter of the Grea ...

  10. codevs 2216 行星序列 线段树+延迟标记(BZOJ 1798)

    2216 行星序列  时间限制: 2 s  空间限制: 256000 KB     题目描述 Description “神州“载人飞船的发射成功让小可可非常激动,他立志长大后要成为一名宇航员假期一始, ...

随机推荐

  1. 【动画进阶】神奇的背景,生化危机4日食 Loading 动画还原

    最近,在 Steam 玩一款老游戏(生化危机 4 重置版),其中,每当游戏转场的过程中,都有这么一个有趣的 Loading 动画: 整个效果有点类似于日食效果,中间一圈黑色,向外散发着太阳般的光芒. ...

  2. Shuffle 题解

    Shuffle 题目大意 给定一个长度为 \(n\) 的 01 序列 \(a\),你可以进行至多一次以下操作: 选定 \(a\) 的一个连续段,满足连续段内恰好有 \(k\) 个 \(1\),将该连续 ...

  3. 关于Halcon中variation_model模型的快速解读。

    十一期间在家用期间研读了下Halcon的variation_model模型,基本上全系复现了他的所有技术要求和细节,这里做个记录. 其实这个模型的所有原理都不是很复杂的,而且Halcon中的帮助文档也 ...

  4. ELK-日志收集-Kibana WEB安全认证

    1.ELK收集MYSQL日志实战: 日志收集存放目录位置: /usr/local/logstash/config/etc/   1)日志采集-存入redis缓存数据库:mysql-redis.conf ...

  5. VK Cup 2016 - Round 1 (CF639)

    A. Bear and Displayed Friends Div2 的题,不写. B. Bear and Forgotten Tree 3 这种东西怎么评蓝的? Description 给定 \(n ...

  6. QT(2)-QRegExp

    QT(2)-QRegExp 1 正则表达式 正则表达式--详情版+常用表达式 Qt中正则表达式(常用) Qt 正则表达式介绍 QRegExp的使用 2 QRegExp 2.1 indexIn int ...

  7. Go语言基准测试(benchmark)三部曲之三:提高篇

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 -<Go语言基准测试(benchmar ...

  8. raspberry pi Pico使用MicroPython变砖后的解决方法

    使用raspberry pi Pico的原因 在硬件产品(单片机)的开发中我们往往需要借助一些额外的仪器/设备进行产品的辅助测试, 假设我们需要一个IO+ADC类型辅助设备, 以往的做法是 原理图-& ...

  9. [USACO2007NOVS] Cow Hurdles S

    题目描述 Farmer John wants the cows to prepare for the county jumping competition, so Bessie and the gan ...

  10. 创建定义store并使用组合式api、选项式api

    在项目根目录创建store文件夹(此步骤和vuex相同) 在步骤一的store文件夹下根据不同的用途场景创建单独的store文件(等同于vuex中分模块). 定义store基本步骤 步骤 导入defi ...