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

题意:给你一个长度n的数列,初始都为0。有三种操作,第一种给第k个位置的数加d。另外一种是查询区间 [l , r] 的总和。第三种是使区间 [l , r] 的值改为离它近期的那个斐波那契数的值。

我刚開始用sum数组存储节点的值。第三种操作是个区间更新,可是区间更新的值不一样。我就想当然的搜到最底部的节点来处理更新,果断T了。后来想了想。事实上能够在节点上再加一个信息。就是这个值下次进行第三种操作要变成的值,在每次进行第一种操作时进行这个值得更新,区间也一样存储下次变化后的总值。这样在进行第三种操作时就能够进行区间更新了比較省时。我不习惯用结构体写,所以多定义了一个数组。

sum数组存储正常值。fuck数组存储下次要变成的斐波那契值。col数组仅仅起标记作用。

事实上这题就是简单的单点更新和区间更新,合到了一起,我还是做的太少。没有在单点更新和区间查询中加pushdown,WA了两发。

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 100100
#define eps 1e-11
#define INF 0x7FFFFFFF
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 long long sum[MAXN<<2];
long long col[MAXN<<2];
long long fuck[MAXN<<2];
long long n,m;
long long f[100];
void pushup(long long rt){
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
fuck[rt] = fuck[rt<<1] + fuck[rt<<1|1];
}
void pushdown(long long rt,long long m){
if(col[rt]){
col[rt<<1] = fuck[rt<<1];
col[rt<<1|1] = fuck[rt<<1|1];
sum[rt<<1] = fuck[rt<<1];
sum[rt<<1|1] = fuck[rt<<1|1];
col[rt] = 0;
}
}
void build(long long l,long long r,long long rt){
col[rt] = 0;
if(l==r){
sum[rt] = 0;
fuck[rt] = 1;
return ;
}
long long m = (l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(long long pos,long long add,long long l,long long r,long long rt){
if(l==r){
sum[rt] += add;
long long p = lower_bound(f,f+90,sum[rt])-f;
if(p-1>=0){
long long fp1 = f[p] - sum[rt];
if(fp1<0) fp1 = -fp1;
long long fp2 = f[p-1] - sum[rt];
if(fp2<0) fp2 = -fp2;
if(fp1>=fp2) fuck[rt] = f[p-1];
else fuck[rt] = f[p];
}
else fuck[rt] = f[p];
return ;
}
pushdown(rt,r-l+1);
long long m = (l+r)>>1;
if(pos<=m) update(pos,add,lson);
else update(pos,add,rson);
pushup(rt);
}
void update2(long long L,long long R,long long l,long long r,long long rt){
if(L<=l&&r<=R){
col[rt] = fuck[rt];
sum[rt] = fuck[rt];
return ;
}
pushdown(rt,r-l+1);
long long m = (l+r)>>1;
if(L<=m) update2(L,R,lson);
if(R>m) update2(L,R,rson);
pushup(rt);
}
long long query(long long L,long long R,long long l,long long r,long long rt){
if(L<=l&&r<=R){
return sum[rt];
}
pushdown(rt,rt-l+1);
long long ans = 0;
long long m = (l+r)>>1;
if(L<=m) ans += query(L,R,lson);
if(R>m) ans += query(L,R,rson);
return ans;
}
int main(){
long long i,j,l,r,k,d,x;
f[0] = 1;
f[1] = 1;
for(i=2;i<90;i++){
f[i] = f[i-1] + f[i-2];
}
while(scanf("%I64d%I64d",&n,&m)!=EOF){
build(1,n,1);
while(m--){
scanf("%I64d%I64d%I64d",&x,&l,&r);
if(x==1){
update(l,r,1,n,1);
}
else if(x==2){
long long ans = query(l,r,1,n,1);
printf("%I64d\n",ans);
}
else{
update2(l,r,1,n,1);
}
}
}
return 0;
}

HDOJ--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. 2019hdu多校3 hdu4893(线段树单点 区间更新

    补这题主要是因为第三个操作要维护区间,而不是点,否则会T. https://vjudge.net/problem/HDU-4893 题意:输入n.q.表示有n个数,初始化默认这n个数都为零,有q次操作 ...

  3. 蓝桥杯Log大侠(线段树单点区间更新)

    标题:Log大侠 atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称Log大侠. 一天,Log大侠的好友 drd 有一些整数序列需要变换,Log大侠正好施展法力... 变换的规则是: ...

  4. ZOJ 2301 Color the Ball 线段树(区间更新+离散化)

    Color the Ball Time Limit: 2 Seconds      Memory Limit: 65536 KB There are infinite balls in a line ...

  5. hdu 1556:Color the ball(线段树,区间更新,经典题)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  6. hdu 1698:Just a Hook(线段树,区间更新)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. UVA 12436-Rip Van Winkle's Code(线段树的区间更新)

    题意: long long data[250001]; void A( int st, int nd ) { for( int i = st; i \le nd; i++ ) data[i] = da ...

  8. hdu1698线段树的区间更新区间查询

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  9. HDU 1556 Color the ball(线段树:区间更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=1556 题意: N个气球,每次[a,b]之间的气球涂一次色,统计每个气球涂色的次数. 思路: 这道题目用树状数组和 ...

  10. zoj3686(线段树的区间更新)

    对线段树的区间更新有了初步的了解... A Simple Tree Problem Time Limit: 3 Seconds      Memory Limit: 65536 KB Given a ...

随机推荐

  1. 「Vue」起步 - vue-router路由与页面间导航

    vue-router 我们知道路由定义了一系列访问的地址规则,路由引擎根据这些规则匹配找到对应的处理页面,然后将请求转发给页进行处理.可以说所有的后端开发都是这样做的,而前端路由是不存在"请 ...

  2. Debian6单用户模式

    开始的时候按"e"进入Grub的编辑界面,这个时候要找:linux /boot/vmlinuz-2.6.32-5-amd64 root=UUID=.......... ro qui ...

  3. 5. 监视和ZooKeeper操作

    ZooKeeper中的写入(write)操作是原子性和持久性的. 写入到大多数ZooKeeper服务器上的持久性存储中,可以保证写操作成功. 无论如何,ZooKeeper的最终一致性模型允许读取(re ...

  4. [转载] Quartz作业调度框架

    转载自http://yangpanwww.iteye.com/blog/797563 Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中.它提 ...

  5. NULL字段对于UNIQUE INDEX失效

  6. 手动安装Eclipse的PyDev插件,重启无效

    想好好学习Python,又不想只用Emeditor开发,于是想到了Eclipse.之前配置过PyDev,很久没用,就放下了.这次重新配置,遇到了不少问题总结如下: 第一,使用网址自动更新.从网上搜了很 ...

  7. CSharpGL(47)你好,Framebuffer!

    CSharpGL(47)你好,Framebuffer! Framebuffer对象(FBO)是一种复杂的OpenGL对象.使用自定义的framebuffer,可以实现离屏渲染,进而实现很多高级功能,例 ...

  8. java中“==”号的运用

    对于值类型,“==”号会判断其是否相等 对于引用类型,“==”对于引用类型则会判断引用(内存地址)是否相同,“==”运算只是调用了对象的equal()方法 public static void mai ...

  9. android引入百度地图之最简单的例子-HelloBaiDuMap

    开发工具 我用的是eclipse,目前这是开发android用的最多的一个工具. 开发准备 首先需要在百度地图开发平台上下载所需要的文档和功能,由于最新版的3.0.0的不是很熟悉,我这里用的是稍旧一点 ...

  10. window环境下npm install node-sass报错

    最近准备想用vue-cli初始化一个项目,需要sass-loader编译: 发现window下npm install node-sass和sass-loader一直报错, window 命令行中提示我 ...