Wow! Such Sequence!

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4893

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.

</big>

##Input
<big>

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.

</big>

##Output
<big>

For each Type 2 ("query sum") operation, output one line containing an integer represent the answer of this query.

</big>

##Sample Input
<big>
1 1
2 1 1
5 4
1 1 7
1 3 17
3 2 4
2 1 5
</big> ##Sample Output
<big>
0
22
</big> <br/>
##题意:
<big>
对一个数组进行若干操作:
1. 将A_k增加x.
2. 查询区间和.
3. 将区间内的数变成离它最近的斐波拉契数.
(注意这个斐波拉契数列是从 1 开始的!!!)
</big> <br/>
##题解:
<big>
很容易想到用线段树维护,关键是如何操作3. 直接每个点维护复杂度太高.
如果一个数被操作3更新为了斐波那契数,那么再次更新时将不改变它的值. 利用这一点来剪枝.
对于树中的每个结点维护一个isfib标记, 表示当前结点所表示的区间内是否均为斐波那契数.
每次操作1更新时,将该点的isfib标志置0; (别忘了,WA了一次)
每次操作3更新时,若处理到某区间均为fib数则返回,否则一直向下处理到单点,并对单点进行更新.
</big> <br/>
##代码:
``` cpp
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <list>
#define LL long long
#define eps 1e-8
#define maxn 101000
#define mod 100000007
#define inf 0x3f3f3f3f
#define mid(a,b) ((a+b)>>1)
#define IN freopen("in.txt","r",stdin);
using namespace std; LL fib[100]; int n;
struct Tree
{
int left,right;
LL sum;
bool isfib;
}tree[maxn<<2]; void pushup(int i) {
tree[i].sum = tree[i<<1].sum + tree[i<<1|1].sum;
tree[i].isfib = tree[i<<1].isfib && tree[i<<1|1].isfib ? 1 : 0;
} void build(int i,int left,int right)
{
tree[i].left=left;
tree[i].right=right; if(left==right){
tree[i].sum = 0;
tree[i].isfib = 0;
return ;
} int mid=mid(left,right); build(i<<1,left,mid);
build(i<<1|1,mid+1,right); pushup(i);
} void update(int i,int x,LL d)
{
if(tree[i].left == tree[i].right){
tree[i].sum += d;
tree[i].isfib = 0;
return;
} int mid=mid(tree[i].left,tree[i].right); if(x<=mid) update(i<<1,x,d);
else update(i<<1|1,x,d); pushup(i);
} LL find_fib(LL x) {
int pos = lower_bound(fib, fib+90, x) - fib;
if(!pos) return fib[pos];
if(abs(fib[pos]-x) < abs(fib[pos-1]-x)) return fib[pos];
return fib[pos-1];
} void update_fib(int i,int left,int right)
{
if(tree[i].isfib) return ;
if(tree[i].left == tree[i].right)
{
tree[i].sum = find_fib(tree[i].sum);
tree[i].isfib = 1;
return ;
} int mid=mid(tree[i].left,tree[i].right); if(right<=mid) update_fib(i<<1,left,right);
else if(left>mid) update_fib(i<<1|1,left,right);
else {
update_fib(i<<1,left,mid);
update_fib(i<<1|1,mid+1,right);
} pushup(i);
} LL query(int i,int left,int right)
{
if(tree[i].left==left&&tree[i].right==right)
return tree[i].sum; int mid=mid(tree[i].left,tree[i].right); if(right<=mid) return query(i<<1,left,right);
else if(left>mid) return query(i<<1|1,left,right);
else return query(i<<1,left,mid)+query(i<<1|1,mid+1,right);
} void init() {
fib[0] = 1; fib[1] = 1;
for(int i=2; i<90; i++) {
fib[i] = fib[i-1] + fib[i-2];
}
} int main(int argc, char const *argv[])
{
//IN; init(); int m;
while(scanf("%d %d", &n,&m) != EOF)
{
build(1, 1, n); while(m--) {
int op, l, r;
scanf("%d %d %d", &op,&l,&r);
if(op == 1) {
update(1, l, (LL)r);
}
else if(op == 2) {
printf("%lld\n", query(1, l, r));
}
else if(op == 3) {
update_fib(1, l, r);
}
}
} return 0;
}

HDU 4893 Wow! Such Sequence! (线段树)的更多相关文章

  1. 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区间上的所以数变成 ...

  2. 线段树 + 区间更新: HDU 4893 Wow! Such Sequence!

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

  3. HDU 4893 Wow! Such Sequence!(2014年多校联合 第三场 G)(线段树)

    磨了一天的线段树,不能说完全搞清楚,只能说有一个大概的了解,靠着模板才把这道题A了,只能说太弱~~! 题意: 初始时有一字符串,全为0. 三种操作: 1 k d - add  把d加到第k个数上去2 ...

  4. Wow! Such Sequence!(线段树4893)

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

  5. HDU 4893 Wow! Such Sequence! (树状数组)

    题意:给有三种操作,一种是 1 k d,把第 k 个数加d,第二种是2 l r,查询区间 l, r的和,第三种是 3 l r,把区间 l,r 的所有数都变成离它最近的Fib数, 并且是最小的那个. 析 ...

  6. hdu 5828 Rikka with Sequence 线段树

    Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...

  7. hdu 4893 Wow! Such Sequence!

    http://acm.hdu.edu.cn/showproblem.php?pid=4893 三种操作: 1 k d - "add" 2 l r - "query sum ...

  8. HDU 5828 Rikka with Sequence (线段树+剪枝优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...

  9. HDU 4893 Wow! Such Sequence!(2014 Multi-University Training Contest 3)

    题意: 有三种操作: 1 x y: 表示给x位置加上y 2 x y:查询[x,y]的区间和 3 x y:将 [x,y] 区间上的数变为最接近的 Fibonacci. 思路: 1 操作按正常单调更新,区 ...

随机推荐

  1. 你用哪种工具进行iOS app自动化功能测试?

    原文见http://www.cocoachina.com/applenews/devnews/2013/1111/7332.html

  2. 基于XMPP的即时通信系统的建立(六)— 开发环境搭建

    服务器端 新建空工程 使用Eclipse新建名为openfire的空java工程. 导入源代码 这里使用的是openfire的openfire_src_3_10_3.zip源码. 导入后将目录src/ ...

  3. bzoj4080

    分组赛时wy大神讲的题,网上都是随机化的题解 我来讲一下正解吧,我们穷举两个点,这两点距离要小于限制 然后我们分别以这两个点为圆心,两点距离为半径画圆 圆圆相交的部分被两点练成线段划分成两部分,不难发 ...

  4. iphone 如何清空UIWebView的缓存

      iphonecachingapplicationcookiescacheperformance I actually think it may retain cached information ...

  5. ffmpeg-2.3.3 configure for android

    #! /bin/shNDK=/usr/local/android-ndk-r10PREBUILT=${NDK}/toolchains/arm-linux-androideabi-4.9/prebuil ...

  6. svn - 常用命令

    基本流程: 获取新的代码,svn up(date),获取最新代码 锁住文件,防止你提交的时候,别人修改,造成冲突,svn lock filename 修改之后,svn add filename,将文件 ...

  7. FFMPEG + SDL音频播放分析

    目录 [hide] 1 抽象流程: 2 关键实现: 2.1 main()函数 2.2 decode_thread()读取文件信息和音频包 2.3 stream_component_open():设置音 ...

  8. 【JS】<c:foreach>用法

    <c:foreach>类似于for和foreach循环   以下是我目前见过的用法: 1.循环遍历,输出所有的元素. <c:foreach items="${list}&q ...

  9. 【转】超全!整理常用的iOS第三方资源 -- 不错

    原文网址:http://www.cocoachina.com/ios/20160121/14988.html 一:第三方插件 1:基于响应式编程思想的oc 地址:https://github.com/ ...

  10. 使用solrj操作solr索引库

    (solrj)初次使用solr的开发人员总是很郁闷,不知道如何去操作solr索引库,以为只能用<五分钟solr4.5教程(搭建.运行)>中讲到的用xml文件的形式提交数据到索引库,其实没有 ...