HDU 4893 线段树延迟标记
题意
初始有一长度为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 线段树延迟标记的更多相关文章
- HDU 3468:A Simple Problem with Integers(线段树+延迟标记)
A Simple Problem with Integers Case Time Limit: 2000MS Description You have N integers, A1, A2, ... ...
- hdu 5023 线段树延迟更新+状态压缩
/* 线段树延迟更新+状态压缩 */ #include<stdio.h> #define N 1100000 struct node { int x,y,yanchi,sum; }a[N* ...
- HDU 4893 线段树的 点更新 区间求和
Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- HDU 4893 线段树裸题
Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- HDU 4893 线段树
比赛时太大意,斐波拉契数列开小了. 题目大意:1个序列,3种操作,改变序列某个数大小,将序列中连续的一段每个数都变成其最近的斐波拉契数,以及查询序列中某一段的数之和. 解题思路:维护add[]数组表示 ...
- Tree(树链剖分+线段树延迟标记)
Tree http://poj.org/problem?id=3237 Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 12 ...
- codevs 1690 开关灯 线段树+延迟标记
1690 开关灯 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这 ...
- HDU4893--Wow! Such Sequence! (线段树 延迟标记)
Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- 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 ...
- codevs 2216 行星序列 线段树+延迟标记(BZOJ 1798)
2216 行星序列 时间限制: 2 s 空间限制: 256000 KB 题目描述 Description “神州“载人飞船的发射成功让小可可非常激动,他立志长大后要成为一名宇航员假期一始, ...
随机推荐
- Go语言系列——11-数组和切片、12-可变参数函数、13-Maps、14-字符串、15-指针、16-结构体、17-方法、18-接口(一)、19-接口(二)、19-自定义集合类型、20-并发入门
文章目录 11-数组和切片 数组 数组的声明 数组是值类型 数组的长度 使用 range 迭代数组 多维数组 切片 创建一个切片 切片的修改 切片的长度和容量 使用 make 创建一个切片 追加切片元 ...
- Python面向对象——反射(hasattr、getattr、setattr、delattr)、内置方法(__str__和__del__)、元类(介绍,创建类的流程,exec,自定义元类)、属性查找
文章目录 反射 内置方法 __str__方法 __del__函数 元类 元类介绍 class关键字创建类的流程分析 补充:exec的用法 自定义元类控制类StanfordTeacher的创建 自定义元 ...
- TIPTOP GP ERP二次开发规范说明
TIPTOP GP ERP二次开发规范说明 TIPTOP ERP共分三大区:topstd(标准区) + toppord(正式区) + toptest(测试区) 标准区 ...
- Go 复合类型之切片类型介绍
Go 复合类型之切片类型 目录 Go 复合类型之切片类型 一.引入 二.切片(Slice)概述 2.1 基本介绍 2.2 特点 2.3 切片与数组的区别 三. 切片声明与初始化 3.1 方式一:使用切 ...
- K8s部署轻量级日志收集系统EFK(elasticsear + filebeat + kibana)
目录 K8s部署EFK(elasticsear + filebeat + kibana)日志收集 一.准备镜像 二.搭建Elasticsearch + kibana 1.在可执行kubectl命令的服 ...
- Caused by: liquibase.exception.ValidationFailedException: Validation Failed:1 change sets check sum
db/changelog/mysql/changelog-0001-307096-1.0.sql::1.0::buoluo.meng was: 8:a5d8f616a121230c204fd2b878 ...
- MyBatis拦截器优雅实现数据脱敏
背景 现代网络环境中,敏感数据的处理是至关重要的.敏感数据包括个人身份信息.银行账号.手机号码等,泄露这些数据可能导致用户隐私泄露.财产损失等严重后果.因此,对敏感数据进行脱敏处理是一种必要的安全措施 ...
- SSL证书链及使用
什么是证书链 证书链简单来说是域名钥证书.CA公钥.根证书形成的一个颁发链条,属于公钥的一部分. 更白话一点,就是证书链文件包含一系列CA机构公钥的证书. 证书链格式 一般证书链格式是.chain,证 ...
- Codeforces Round #700 (Div. 2) A~C题解
写在前边 链接:Codeforces Round #699 (Div. 2) A. Yet Another String Game 链接:A题链接 题目大意: 给定一个字符串,有两位同学来操作这个字符 ...
- 【Javaweb】html frame标签的使用 | 导航栏右侧内容的实现
问题的产生: 是我和同伴做了一个导航栏,但是我们不知道怎么实现右侧内容的切换 然后我们查了很多资料,但是有一些是垂直的,但是就如图可见,我们是水平的,那么怎么实现水平切换呢? 上网看到了frame标签 ...