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. POJ 1808 Quadratic Residues(平方剩余相关)

    题目链接:http://poj.org/problem?id=1808 题意:如下.对于素数p,若存在x使得x^2%p=a,则其值为1.否则为-1.现在给出a.p,计算其值. 思路: 若a为正数则利用 ...

  2. tengine lua 开源一 调用内部接口高效发送文件

    tengine  lua 开源一 调用内部接口高效发送文件 开源自己封装的sendfile 模块,可以高效的通过lua发送文件 源码地址:https://github.com/weinyzhou/Lu ...

  3. [HIHO1318]非法二进制(动态规划)

    题目链接:http://hihocoder.com/problemset/problem/1318 题意:是个dp题.考虑二进制数为i位的时候,无非有两种情况:新添加的一位为0或者1. 为0的时候,那 ...

  4. git push提示或错误

    当 git 和 gerrit 一起使用的时候,你创建了一个 tag,现在需要 push 到远程仓库,当你没有权限的时候,会出现如下提示: $ git push origin v20150203 Tot ...

  5. HDU 4923

    题目大意: 给出一串序列Ai{0,1},求一个序列Bi[0,1](Bi<Bi+1),使得sigama(Ai-Bi)^2最小 思路: 若B相同,则取A的平均数可使方差最小 若B有序,   若A== ...

  6. Share SDK 第三方登录

    import java.util.HashMap; import org.apache.http.Header; import android.app.Activity; import android ...

  7. LeetCode Binary Tree Preorder Traversal 先根遍历

    题意:给一棵树,求其先根遍历的结果. 思路: (1)深搜法: /** * Definition for a binary tree node. * struct TreeNode { * int va ...

  8. ffmpeg windows 雪花声解决方法

    替换所有文件里的<math.h>为<mathimf.h>即可. 我用ffmpeg-0.6.3版测试时,好像mathimf.h文件和其他文件有冲突,需要修改源码. 和qdm2.c ...

  9. Memcache应用场景介绍,说明

    面临的问题 对于高并发高访问的Web应用程序来说,数据库存取瓶颈一直是个令人头疼的问题.特别当你的程序架构还是建立在单数据库模式,而一个数据池连接数峰 值已经达到500的时候,那你的程序运行离崩溃的边 ...

  10. Meta标签详解(转)

    引言 您的个人网站即使做得再精彩,在“浩瀚如海”的网络空间中,也如一叶扁舟不易为人发现,如何推广个人网站,人们首先想到的方法无外乎以下几种: ● 在搜索引擎中登录自己的个人网站 ● 在知名网站加入你个 ...