Wow! Such Sequence!

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2234    Accepted Submission(s): 657

Problem Description
Recently, Doge got a funny birthday present from his new friend, Protein Tiger from St. Beeze College. No, not cactuses. It's a mysterious blackbox.

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.

 
Input
Input contains several test cases, please process till EOF.
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.

 
Output
For each Type 2 ("query sum") operation, output one line containing an integer represent the answer of this query.
 
Sample Input
1 1
2 1 1
5 4
1 1 7
1 3 17
3 2 4
2 1 5
 
Sample Output
0
22
 
Author
Fudan University
 
Source

【题目分析】

这题相比于裸的线段树区间更新有了一些难度。
我们在每个结点中设一个fib,表示离sum最近的fibnacci数,每次区间更新时,就将sum的值更新为fib。fib的值只有在单点更新的过程中才会改变,也就是说当sum值改变的时候fib才改变,因为当sum变为fib后,离sum最近的fibnacci数还是fib值。

lazy----记录该点以下的孩子结点是否需要更新。

我用long long ,然后用了%lld输入,不知道杭电不支持%lld,debug了半天,TLE了20多次,后来改%lld为%I64d就过了,哭死QAQ...


//Memory   Time
// K MS
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<iomanip>
#include<string>
#include<climits>
#include<cmath>
#define MAX 100010
#define LL long long
using namespace std;
LL n,m;
LL ans;
LL f[60]; struct Tree
{
LL l,r;
LL sum,fib;
bool lazy;
};
Tree tree[MAX*3]; LL Find(LL x)
{
if(x<=0)return 1;
LL ldis,rdis;
for(int i=0;i<59;++i)
{
if(f[i]<=x&&f[i+1]>=x)
{
ldis=x-f[i];
rdis=f[i+1]-x;
return ldis<=rdis?f[i]:f[i+1];
}
}
} void pushup(LL x)
{
LL tmp=x<<1;
tree[x].sum=tree[tmp].sum+tree[tmp+1].sum;
tree[x].fib=tree[tmp].fib+tree[tmp+1].fib;
} void pushdown(LL x)
{
if(!tree[x].lazy)return;
tree[x].lazy=0;
if(tree[x].l==tree[x].r)return;
LL tmp=x<<1;
tree[tmp].lazy=tree[tmp+1].lazy=1;
tree[tmp].sum=tree[tmp].fib;
tree[tmp+1].sum=tree[tmp+1].fib;
} void build(LL l,LL r,LL x)
{
tree[x].l=l,tree[x].r=r;
tree[x].sum=0,tree[x].fib=1,tree[x].lazy=0;
if(l==r)return;
LL tmp=x<<1;
LL mid=(l+r)>>1;
build(l,mid,tmp);
build(mid+1,r,tmp+1);
pushup(x);
} void add(LL x,LL k,LL num)
{
if(tree[x].l==tree[x].r)
{
tree[x].sum+=num;
tree[x].fib=Find(tree[x].sum);
return;
}
if(tree[x].lazy)
pushdown(x);
LL tmp=x<<1;
LL mid=(tree[x].l+tree[x].r)>>1;
if(k<=mid)
add(tmp,k,num);
else if(k>mid)
add(tmp+1,k,num);
pushup(x);
} void change(LL l,LL r,LL x)
{
if(r<tree[x].l||l>tree[x].r)return;
if(l<=tree[x].l&&r>=tree[x].r)
{
tree[x].sum=tree[x].fib;
tree[x].lazy=1;
return;
}
if(tree[x].lazy)pushdown(x);
LL tmp=x<<1;
LL mid=(tree[x].l+tree[x].r)>>1;
if(r<=mid)
change(l,r,tmp);
else if(l>mid)
change(l,r,tmp+1);
else
{
change(l,mid,tmp);
change(mid+1,r,tmp+1);
}
pushup(x);
} void query(LL l,LL r,LL x)
{
if(r<tree[x].l||l>tree[x].r)return;
if(l<=tree[x].l&&r>=tree[x].r)
{
ans+=tree[x].sum;
return;
}
if(tree[x].lazy)
pushdown(x);
LL tmp=x<<1;
LL mid=(tree[x].l+tree[x].r)>>1;
if(r<=mid)
query(l,r,tmp);
else if(l>mid)
query(l,r,tmp+1);
else
{
query(l,mid,tmp);
query(mid+1,r,tmp+1);
}
pushup(x);
} int main()
{
// freopen("cin.txt","r",stdin);
// freopen("cout.txt","w",stdout);
f[0]=f[1]=1;
for(int i=2;i<60;++i) f[i]=f[i-1]+f[i-2];
while(scanf("%I64d %I64d",&n,&m)!=EOF)
{
build(1,n,1);
LL a,b,c;
while(m--)
{
scanf("%I64d %I64d %I64d",&a,&b,&c);
if(a==1)
add(1,b,c);
else if(a==2)
{
ans=0;
query(b,c,1);
printf("%I64d\n",ans);
}
else
change(b,c,1);
}
}
return 0;
}

  

线段树 + 区间更新: HDU 4893 Wow! Such Sequence!的更多相关文章

  1. 线段树 + 区间更新 ----- HDU 4902 : Nice boat

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  2. 线段树-区间更新-HDU 1689

    #include <iostream> #include <cstdio> #include <string> #include <cstring> # ...

  3. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

  4. HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...

  5. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  6. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  7. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  8. HDU 1556 Color the ball(线段树区间更新)

    Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...

  9. HDU 1698 线段树 区间更新求和

    一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...

随机推荐

  1. windowns 2008(apache2.2.25 x86 openssl0.98y) 升级openssl1.0.1e(为了支持小程序接口TLS1.2)

    原来只知道微信小程序,服务器接口必须支持 https, 所以在搭建环境的时候没有注意, 只是在原来已有的系统框架上,稳健升级,把apache2.2.25 X86_no_openssl升级为了apach ...

  2. Windows 7 添加SSD硬盘后重启卡住正在启动

    楼主办公电脑,原来只配置了一块机械硬盘,用着总很不顺心,于是说服领导给加了块SSD固态硬盘. 操作如下: 1.在PE下分区格式化新固态硬盘,将原来机械硬盘的C盘GHOST备份后还原到新固态硬盘: 2. ...

  3. Java Web(六) EL表达式

    这也是属于JSP范围内的知识,使用EL表达式,能更好的使用JSP中的各种内置对象和作用域,说点闲话,马上要出去实习了,有点恐慌,可能这是马上要出去工作的学生的通病,继续努力把,兵来将挡水来土掩, -- ...

  4. zabbix 实现 iptables 监控

    安装iptstate # yum install iptstate 配置zabbix key iptables.conf # cat /etc/zabbix/zabbix_agentd.d/iptab ...

  5. 当update的查询条件是数组的时候,upsert会失效

    不管是findOneAndUpdate还是update方法,只要他们的查询条件是数组,upsert就会失效,比如: //这段代码只会更新已存在的数据,不存在的不会插入 tagModel.update( ...

  6. android studio - Indexing paused due to batch updated

    傻逼的 Android Studio  又开抽疯了....  日 打开项目就出现   Indexing paused due to batch updated ,并且半天没反应........ 解决办 ...

  7. Asp.net Core 项目API接口服务器部署

    Windows server 2008服务器部署: DotNetCore.1.0.0.RC2-WindowsHosting 或者DotNetCore.1.0.5_1.1.2-WindowsHostin ...

  8. python 三元表达式 if for 构建List 进阶用法

    1.简单的for...[if]...语句 Python中,for...[if]...语句一种简洁的构建List的方法,从for给定的List中选择出满足if条件的元素组成新的List,其中if是可以省 ...

  9. layui的table中使用switch

    {{# if(false){ }} <input type="checkbox" name="switch" lay-skin="switch& ...

  10. HP管理工具System Management Homepage安装配置

    如果用HP的启动光盘进行系统安装时,HP SMH 及相关组件会自动安装完成,但如果是用操作系统光盘进行系统安装,则HP SMH相关组件需要手动进行安装及相关设置!HP SMH由三部分组成:HP Sys ...