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. tc 2014 college tour 250 500

    题意: You are given a long long n. Return the largest divisor of n that is a perfect square. That is, ...

  2. Android系列之Fragment(一)----Fragment加载到Activity当中

    Android上 的界面展示都是通过Activity实现的,Activity实在是太常用了.但是Activity也有它的局限性,同样的界面在手机上显示可能很好看, 在平板上就未必了,因为平板的屏幕非常 ...

  3. PHPnow 升级后 PHP不支持GD、MySQL

    来自http://tunps.com/php-unsupport-gd-and-mysql-after-upgrade-phpnow 最近磁盘格式化误操作后,最近两天都在忙于数据恢复,现在才恢复正常. ...

  4. Java [Leetcode 125]Valid Palindrome

    题目描述: Given a string, determine if it is a palindrome, considering only alphanumeric characters and ...

  5. 专题:Windows编译x264、SDL、faac、ffmpeg过程

    Windows上编译ffmpeg完整过程,包括编译x264.SDL.faac.在Windows上编译ffmpeg需要用MinGW+msys,本专题用于记录编译过程中遇到的各种问题及解决方法,转载请注明 ...

  6. FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法。。

    [原创] RFC3984是H.264的baseline码流在RTP方式下传输的规范,这里只讨论FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法. 1.单个NAL包单元 12字节 ...

  7. liux之我用过的zip解压命令

    用途说明 zip文件是一种常用的压缩文件格式,WinZip.WinRar等压缩软件都支持zip文件格式,就连java的jar包也是zip格式 的,Firefox插件xpi文件也是zip格式的.Linu ...

  8. 【转】话说我打算一天学完object c语法,系列1--------来自书Objective-c程序设计

    原文网址:http://blog.csdn.net/zengraoli/article/details/8993466 类型: NSString NSInteger NSLong控制台输出 NSObj ...

  9. IE下JS接受ActiveX控件方法

    1.常规写法 <SCRIPT type="text/javascript" FOR="activexID" EVENT="onXXXevent( ...

  10. android改变字体的颜色的三种方法

    写文字在Android模拟器中的方法 法一: main.xml配置文件: <TextView android:id="@+id/tv" android:layout_widt ...