题意:一个初始为0的数组,支持三种操作:1、向第k个数添加d,(|d| < 2^31);2、把[l, r]区间内的数字都换成与它最相近的Fibonacci数;3、询问[l, r]区间的和。

思路:初始化Fibonacci数组,longlong 类型内90个就够用了。

  线段树区间查询,用lazy标记, sgt[]记录线段树各个节点的区间和, fib_num_sum[]记录与各个叶子节点当前值最接近的Fibonacci数,传递到区间fib_num_sum[]就是区间Fibonacci数的和。

  操作1时第k个数的sgt[]+= d,同时更新fib_num_sum[]。操作2即把找到的区间sgt[]=fib_num_sum[]。操作3,直接返回区间sgt[]值。

AC代码:

 #include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 100005
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
long long sgt[maxn<<], fib_num_sum[maxn<<];
bool lazy[maxn<<];
long long fib[];
void init_fib()
{
fib[] = fib[] = ;
for(int i = ; i < ; i++){
fib[i] = fib[i-] + fib[i-];
}
} void push_up(int rt)
{
sgt[rt] = sgt[rt<<] + sgt[rt<<|];
fib_num_sum[rt] = fib_num_sum[rt<<] + fib_num_sum[rt<<|];
} void push_down(int rt)
{
if(lazy[rt]){
lazy[rt<<] = lazy[rt<<|] = ;
lazy[rt] = ;
sgt[rt<<] = fib_num_sum[rt<<];
sgt[rt<<|] = fib_num_sum[rt<<|];
}
} long long find_fib(long long x)
{
int a = lower_bound(fib, fib+, x) - fib;
if(x && fib[a] - x >= x - fib[a-]) return fib[a-];
return fib[a];
} void build(int l, int r, int rt)
{
lazy[rt] = , fib_num_sum[rt] = ;
if(l == r){
sgt[rt] = ;
return;
}
int m = (r + l) >>;
build(lson);
build(rson);
push_up(rt);
}
void add(int l, int r, int rt, int k, int d)
{
if(l == r) {
sgt[rt] += d;
fib_num_sum[rt] = find_fib(sgt[rt]);
return;
}
push_down(rt);
int m = (l+r)>>;
if(m >= k) add(lson, k, d);
if(m < k) add(rson, k, d);
push_up(rt);
} void change(int l, int r, int rt, int L, int R)
{
if(L <= l&&r <= R){
lazy[rt] = ;
sgt[rt] = fib_num_sum[rt];
return;
}
push_down(rt);
int m = (r+l)>>;
if(L <= m) change(lson, L, R);
if(m < R) change(rson, L, R);
push_up(rt);
} long long query(int l, int r, int rt, int L, int R)
{
if(L <= l&&r <= R) return sgt[rt];
push_down(rt);
int m = (r+l)>>;
long long ans = ;
if(L <= m) ans += query(lson, L, R);
if(m < R) ans += query(rson, L, R);
return ans;
} int n, m;
void work()
{
build(, n, );
while(m--){
int a; scanf("%d", &a);
if(a == ) {
int k, d; scanf("%d%d", &k, &d);
add(, n, , k, d);
}
if(a == ) {
int l, r; scanf("%d%d", &l, &r);
printf("%I64d\n", query(, n, , l, r));
}
if(a == ) {
int l, r; scanf("%d%d", &l, &r);
change(, n, , l, r);
}
}
} int main()
{
init_fib();
while(scanf("%d%d", &n, &m) != EOF) work();
return ;
}

最新文章

  1. ecshop后台新功能及权限的添加
  2. 【转】C++析构函数为什么要为虚函数
  3. Complete The Pattern #6 - Odd Ladder
  4. Bzoj 1878: [SDOI2009]HH的项链 莫队
  5. 动态include与静态include的区别
  6. C互质个数
  7. phpstudy 虚拟主机域名配置注意问题
  8. bzoj 3631: [JLOI2014]松鼠的新家
  9. 浅谈MySQL架构体系
  10. Spring-AspectJ 配置文件
  11. hadoop伪分布环境快速搭建
  12. 中国顶级黑客X档案
  13. EM算法之GMM聚类
  14. Intel 面试(就不该报外企,英语是硬伤)
  15. jquery ajax context
  16. secureCRT 字体颜色、文件夹和文件显示的颜色
  17. v​n​c​服​务​​安​装​与配置
  18. android2.1中&lt;shape&gt;圆角的bug
  19. unity材质球贴图滚动
  20. HDU 1754 I Hate It (线段树)

热门文章

  1. poj 1113 Wall
  2. JS 时分秒验证
  3. Java多线程——&lt;七&gt;多线程的异常捕捉
  4. Binary Indexed Tree 分类: ACM TYPE 2014-08-29 13:08 99人阅读 评论(0) 收藏
  5. ACM入门记
  6. ios 环境配置网址
  7. 【QT】找茬外挂制作
  8. DB2 DATE类型在显示的时候,带有00:00:00,去掉的方法,使用VARCHAR()函数
  9. Jenkins+Maven+Git CI环境搭建手册
  10. MongoDB (八) MongoDB 文档操作