HDU4893:Wow! Such Sequence!(段树lazy)
After some research, Doge found that the box is maintaining a sequence an of n numbers internally, initially all numbers are zero, and there are THREE "operations":
1.Add d to the k-th number of the sequence.
2.Query the sum of ai where l ≤ i ≤ r.
3.Change ai to the nearest Fibonacci number, where l ≤ i ≤ r.
4.Play sound "Chee-rio!", a bit useless.
Let F0 = 1,F1 = 1,Fibonacci number Fn is defined as Fn = Fn - 1 + Fn - 2 for n ≥ 2.
Nearest Fibonacci number of number x means the smallest Fn where |Fn - x| is also smallest.
Doge doesn't believe the machine could respond each request in less than 10ms. Help Doge figure out the reason.
For each test case, there will be one line containing two integers n, m.
Next m lines, each line indicates a query:
1 k d - "add"
2 l r - "query sum"
3 l r - "change to nearest Fibonacci"
1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, |d| < 231, all queries will be valid.
1 1
2 1 1
5 4
1 1 7
1 3 17
3 2 4
2 1 5
0
22#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define ll __int64
#define maxn 100005
#define ls l,mid,2*i
#define rs mid+1,r,2*i+1
#define lson 2*i
#define rson 2*i+1
struct node
{
int l,r;
ll e,f;//e为该区间的和,f为其近期的斐波那契数
int flag,len;//flag,标记这个区间内是否斐波那契数,len为长度
} a[maxn<<2];
int n,m;
ll f[90] = {1,1}; ll pabs(ll a)
{
return a<0?-a:a;
} void PushDown(int i,int m)
{
if(a[i].flag)
{
a[lson].flag = a[rson].flag = a[i].flag;
a[lson].len = a[i].flag*(m-m>>1);
a[rson].len = a[i].flag*(m>>1);
a[lson].e = a[lson].f;
a[rson].e = a[rson].f;
a[i].flag = 0;
}
} void PushUp(int i)
{
a[i].e = a[lson].e+a[rson].e;
a[i].f = a[lson].f+a[rson].f;
} void init(int l,int r,int i)
{
a[i].flag = a[i].len = 0;
a[i].l = l;
a[i].r = r;
a[i].e = 0;
if(l == r)
{
a[i].f = 1;
return;
}
int mid = (l+r)>>1;
init(ls);
init(rs);
PushUp(i);
} void add(int pos,int m,int l,int r,int i)
{
if(pos<l || pos>r) return ;
if(l == r)
{
if(a[i].flag)
{
a[i].e = m+a[i].f;
a[i].flag = 0;
a[i].len = 0;
}
else a[i].e+=m;
int p = lower_bound(f,f+80,a[i].e)-f;
if(!p)
a[i].f = 1;
else if(pabs(a[i].e-f[p])<pabs(a[i].e-f[p-1]))
a[i].f = f[p];
else
a[i].f = f[p-1];
return ;
}
PushDown(i,r-l+1);
int mid = (l+r)>>1;
if(pos<=mid) add(pos,m,ls);
else add(pos,m,rs);
PushUp(i);
} ll query(int L,int R,int l,int r,int i)
{
if(R<l || L>r) return 0;
else if(L<=l && R>=r) return a[i].e;
PushDown(i,r-l+1);
ll ans = 0;
int mid = (l+r)>>1;
if(L<=mid)
ans += query(L,R,ls);
if(R>mid)
ans += query(L,R,rs);
return ans;
} void change(int L,int R,int l,int r,int i)
{
if(R<l || L>r) return ;
if(L<=l && R>=r)
{
a[i].e = a[i].f;
a[i].flag = 1;
a[i].len = r-l+1;
return ;
}
PushDown(i,r-l+1);
int mid = (l+r)>>1;
if(L<=mid)
change(L,R,ls);
if(R>mid)
change(L,R,rs);
PushUp(i);
} int main()
{
int i,j,x,k,d,l,r;
for(i = 2; i<80; i++)
f[i] = f[i-1]+f[i-2];
while(~scanf("%d%d",&n,&m))
{
init(1,n,1);
while(m--)
{
scanf("%d",&x);
if(x == 1)
{
scanf("%d%d",&k,&d);
add(k,d,1,n,1);
}
else
{
scanf("%d%d",&l,&r);
if(x == 2)
printf("%I64d\n",query(l,r,1,n,1));
else
change(l,r,1,n,1);
}
}
} return 0;
}
HDU4893:Wow! Such Sequence!(段树lazy)的更多相关文章
- 2014多校3 Wow! Such Sequence!段树
主题链接:http://acm.hdu.edu.cn/showproblem.php? pid=4893 这个问题还真是纠结啊--好久不写线段树的题了.由于这几天学伸展树.然后认为线段树小case了. ...
- Wow! Such Sequence!(线段树4893)
Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- hdu 4893 Wow! Such Sequence!(线段树)
题目链接:hdu 4983 Wow! Such Sequence! 题目大意:就是三种操作 1 k d, 改动k的为值添加d 2 l r, 查询l到r的区间和 3 l r. 间l到r区间上的所以数变成 ...
- hdu4893 Wow! Such Sequence!
线段树结点上保存一个一般的sum值,再同一时候保存一个fbsum,表示这个结点表示的一段数字若为斐波那契数时的和 当进行3操作时,仅仅用将sum = fbsum就可以 其它操作照常进行,仅仅是单点更新 ...
- 线段树 + 区间更新: HDU 4893 Wow! Such Sequence!
Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- HDU 4893 Wow! Such Sequence! (线段树)
Wow! Such Sequence! 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4893 Description Recently, Doge ...
- HDU 1394 Minimum Inversion Number (数据结构-段树)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- PKU A Simple Problem with Integers (段树更新间隔总和)
意甲冠军:一个典型的段树C,Q问题,有n的数量a[i] (1~n),C, a, b,c在[a,b]加c Q a b 求[a,b]的和. #include<cstdio> #include& ...
- HDU 6356.Glad You Came-线段树(区间更新+剪枝) (2018 Multi-University Training Contest 5 1007)
6356.Glad You Came 题意就是给你一个随机生成函数,然后从随机函数里确定查询的左右区间以及要更新的val值.然后最后求一下异或和就可以了. 线段树,区间最大值和最小值维护一下,因为数据 ...
随机推荐
- Ubuntu常用软件推荐,图文详细说明及下载
抛开Windows,其实在任何一款Linux发行版本中,我们都有超级大量的软件来安装,使用.这次的教程,我就以Ubuntu为例,来给大家推荐一些我认为不错的软件 声明: 1.本文提到的全部软件,都在文 ...
- Ubuntu 12.04开启3D桌面特效
1.设定软件源,更新软件 点击左边栏Dash主页(Ubuntu图标),输入更新管理器,会出现更新管理器,打开后点设置,弹出软件源对话框,为确保能够正常更新,选主服务器 点击检查,更新完后,点重启 2. ...
- unity3D实际的原始视频游戏开发系列讲座12之U3D的2D为了开发实战的新方法
U3D的2D为了开发实战的新方法 (Unity3d-4.x的打飞机2D游戏开发新的方法应用 ) 大纲介绍:不使用NGUI和TK2d插件, 使用 U3D内置强大的最大的工具. 开发过程设计到例 ...
- Silverlight的Socket通信
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPwAAAGwCAIAAAACJJ+TAAAgAElEQVR4nO2deXgT5534Rdhskme7+9
- C# The process cannot access the file because it is being used by another process
C# The process cannot access the file because it is being used by another process The process cann ...
- 转: 第二章 IoC Annotation注入
http://blog.csdn.net/p_3er/article/details/9231307 1.命名空间 使用Annotation的方式,需要在spring的配置文件中配置命名空间.命名空间 ...
- 【SICP读书笔记(三)】练习2.18 --- 表序列的reverse方法
来自练习2.18 请定义出过程reverse,它以一个表为参数,返回的表中所包含的元素与参数表相同,但排列顺序与参数表相反: (reverse (list 1 4 9 16 25)) (25 16 9 ...
- drools6 基本使用 -- 2
续drools6 基本使用1 http://blog.csdn.net/cloud_ll/article/details/26979355 8. 创建src/main/test folder.把dro ...
- linux挂载U盘,及乱码问题解决
1. 首先使用切换到root用户. 2. 使用fdisk -l命令查看磁盘信息,找到u盘(能够依据显示的大小确定) 3. 在/mnt下创建挂载点,比如创建usb目录:mkdir /mnt/usb 4. ...
- Maven学习笔记(三) :Maven使用入门
编写POM: Maven项目的核心是pom.xml.POM(Project Object Model,项目对象模型)定义了项目的基本信息,用于描写叙述项目怎样构建,声明项目依赖,等等. ...