HDU 4893 Wow! Such Sequence! (线段树)
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! (线段树)的更多相关文章
- 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区间上的所以数变成 ...
- 线段树 + 区间更新: 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!(2014年多校联合 第三场 G)(线段树)
磨了一天的线段树,不能说完全搞清楚,只能说有一个大概的了解,靠着模板才把这道题A了,只能说太弱~~! 题意: 初始时有一字符串,全为0. 三种操作: 1 k d - add 把d加到第k个数上去2 ...
- 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! (树状数组)
题意:给有三种操作,一种是 1 k d,把第 k 个数加d,第二种是2 l r,查询区间 l, r的和,第三种是 3 l r,把区间 l,r 的所有数都变成离它最近的Fib数, 并且是最小的那个. 析 ...
- hdu 5828 Rikka with Sequence 线段树
Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...
- hdu 4893 Wow! Such Sequence!
http://acm.hdu.edu.cn/showproblem.php?pid=4893 三种操作: 1 k d - "add" 2 l r - "query sum ...
- HDU 5828 Rikka with Sequence (线段树+剪枝优化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...
- 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 操作按正常单调更新,区 ...
随机推荐
- SQLserver临时表
IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME='#temp') DROP TABLE #tempGOSELECT ID,XM,ADDDW INTO #t ...
- Android开发之权限列表
权限定义 功能 android.permission.ACCESS_CHECKIN_PROPERTIES 允许读写访问"properties"表在checkin数据库中,改值可以修 ...
- [HDOJ1698]Just a Hook(线段树,区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 陈题,更新后查询所有叶节点的和.撸一遍模版,形成自己的风格. #include <algo ...
- 分解成3NF的保持函数依赖的分解算法:
转换成3NF的保持函数依赖的分解算法: ρ={R1<U1,F1>,R2<U2,F2>,...,Rk<Uk,Fk>}是关系模式R<U,F>的一个分解,U= ...
- RPi 2B Raspbian system install
/***************************************************************************** * RPi 2B Raspbian系统安装 ...
- 04day1
无穷的数列 找规律 [问题描述] 有一个无穷序列如下: 110100100010000100000- 请你找出这个无穷序列中指定位置上的数字. [输入] 第一行一个正整数 N,表示询问次数:接下来的 ...
- 【转】linux下a.out >outfile 2>&1重定向问题
原文网址:http://blog.chinaunix.net/uid-25909722-id-2912890.html 转自:http://blog.chinaunix.net/space.php?u ...
- Kotlin 语言高级安卓开发入门
过去一年,使用 Kotlin 来为安卓开发的人越来越多.即使那些现在还没有使用这个语言的开发者,也会对这个语言的精髓产生共鸣,它给现在 Java 开发增加了简单并且强大的范式.Jake Wharton ...
- mybatis中的变量#与$
ibatis中使用select top #num# * from tableName出现错误.由于初次用ibatis还不知道在它里边拼写SQL语句的一些规则,导致一些自认为很平常的SQL语句,在它这里 ...
- [转载] python+Eclipse+pydev环境搭建
转自:http://www.cnblogs.com/Bonker/p/3584707.html 编辑器:Python 自带的 IDLE 简单快捷, 学习Python或者编写小型软件的时候.非常有用. ...