HDU 4893 2014多校三 线段树
给定一个初始都为0的序列,有三种操作,前两种比较正常,一个是对某个位置的数add k,另一个是query区间和。然后比较麻烦的是第三个操作,把某个区间里面的每个值改成离它最近的Fibonacci数,如果存在左右两个离它近的,优先取左边数值小的
一看到前两个操作马上就想上手敲树状数组,后来看到第三个就有点傻眼了,思维当时一直停留在怎么快速改值。。但忽略了题目本身要求什么,只有操作2才是输出,也就是只要求区间和值而且,其他两个都是操作而已,在聪哥的提醒下,知道对线段树开两个值记录+一个懒惰标记,一个值d记录正常的区间和值,另一个sf记录当前的fibanacci数值和
懒惰标记记录当前区间是否被3操作过,若被标记了,下次query就是返回sf,否则返回d。
不过一开始思路还是有点不清晰,还WA了几发。明显按上面的转化就是一个普通的单点更新+懒惰标记+区间查询的线段树了嘛
主要错在pushdown函数和3操作处理上。没分清模块
首先3操作命名为fix,fix找到对应的区间后,就进行懒惰标记,顺便把当前区间d改为sf值,然后向上传递。
add操作,首先,找到最后单点即进行更新操作,否则pushdown,把懒惰标记传递下去,在标记里面也是要对d=sf操作的,最后向上传递结果
query就更明显了,找区间return sf 或者 d,没找到就先pushdown
一开始糊里糊涂,pushdown又没push好,还没修改当前的值
比赛的时候还是有点糊里糊涂,线段树功底还不够,还要继续练
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define LL __int64
using namespace std;
const int N = ;
LL f[];
LL d[N<<],flag[N<<],sf[N<<];
LL pref[N];
int n,q;
void init()
{
LL tmp=1LL<<;
f[]=f[]=;
for (int i=;i<=;i++){
f[i]=f[i-]+f[i-]; }
} void build(int rt ,int l,int r)
{
flag[rt]=d[rt]=;
if (l>=r){
sf[rt]=;
return;
}
int mid=(l+r)>>;
build(lson);
build(rson);
sf[rt]=sf[rt<<]+sf[rt<<|];
}
void change(int rt)
{
d[rt]=sf[rt];
}
void up(int rt,int l,int r)
{
d[rt]=d[rt<<]+d[rt<<|];
sf[rt]=sf[rt<<]+sf[rt<<|]; }
void pushdown(int rt,int l,int r)
{
int mid=(l+r)>>;
if (flag[rt]== || l>=r) return;
flag[rt<<]=flag[rt<<|]=flag[rt];
d[rt<<]=sf[rt<<];
d[rt<<|]=sf[rt<<|];
flag[rt]=;
}
void fix(int L,int R,int rt,int l,int r)
{
if (flag[rt]==) return;
if (L<=l && r<=R){
flag[rt]=;
d[rt]=sf[rt];
return;
}
int mid=(l+r)>>;
if (R<=mid) fix(L,R,lson);
else
if (L>mid) fix(L,R,rson);
else{
fix(L,R,lson);
fix(L,R,rson);
}
if (flag[rt<<]== && flag[rt<<|]==){
flag[rt]=;
}
up(rt,l,r);
}
void add(int loc,LL val,int rt,int l,int r)
{
if (l>=r)
{
flag[rt]=;
d[rt]+=val;
int loc=lower_bound(f,f+,d[rt])-f;
sf[rt]=f[loc];
if (loc>){
if (d[rt]-f[loc-]<=f[loc]-d[rt]){
sf[rt]=f[loc-];
}
}
return;
}
pushdown(rt,l,r);
int mid=(l+r)>>;
if (loc<=mid) add(loc,val,lson);
else add(loc,val,rson);
up(rt,l,r);
} LL query(int L,int R,int rt,int l,int r)
{
if (L<=l && r<=R){
if (flag[rt]) return sf[rt];
else return d[rt];
}
pushdown(rt,l,r);
int mid=(l+r)>>;
if (R<=mid) return query(L,R,lson);
else
if (L>mid) return query(L,R,rson);
else
{
LL ret1=query(L,R,lson);
LL ret2=query(L,R,rson);
return ret1+ret2;
}
}
int main()
{
init();
int op;
while (scanf("%d%d",&n,&q)!=EOF)
{
build(,,n);
while (q--)
{
scanf("%d",&op);
if (op==){
int a;
LL b;
scanf("%d%I64d",&a,&b);
add(a,b,,,n);
}
else
if (op==){
int a,b;
scanf("%d%d",&a,&b);
LL ans=query(a,b,,,n);
printf("%I64d\n",ans);
}
else{
int a,b;
scanf("%d%d",&a,&b);
fix(a,b,,,n);
}
}
}
return ;
}
HDU 4893 2014多校三 线段树的更多相关文章
- HDU 4960 Handling the past 2014 多校9 线段树
首先确定的基本思想是按时间离散化后来建线段树,对于每个操作插入到相应的时间点上 但是难就难在那个pop操作,我之前对pop操作的处理是找到离他最近的那个点删掉,但是这样对于后面的peak操作,如果时间 ...
- HDU 4893 Wow! Such Sequence! (线段树)
Wow! Such Sequence! 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4893 Description Recently, Doge ...
- hdu 5274 Dylans loves tree(LCA + 线段树)
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 3074.Multiply game-区间乘法-线段树(单点更新、区间查询),上推标记取模
Multiply game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)
HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意: 给一个序列由 ...
- HDU 5029 Relief grain(离线+线段树+启发式合并)(2014 ACM/ICPC Asia Regional Guangzhou Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5029 Problem Description The soil is cracking up beca ...
- hdu 1556:Color the ball(线段树,区间更新,经典题)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- hdu 1166敌兵布阵(线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) M ...
- 暑期训练狂刷系列——Hdu 1698 Just a Hook (线段树区间更新)
题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=1698 题目大意: 有一个钩子有n条棍子组成,棍子有铜银金三种组成,价值分别为1,2,3.为了对付每场 ...
随机推荐
- shell脚本中 “set -e” 的作用
#!/bin/bash set -e command 1command 2 每个脚本都应该在文件开头加上set -e,这句语句告诉bash如果任何语句的执行结果不是true则应该退出.这样的好处是防止 ...
- python 中的富文本编译器
第一种方式: 1,pip install django-tinymce 2,在INSTALL_APPS里面添加tinymce 在站点中使用: 配置setting.py TINYMCE_D ...
- 等级保护2.0-mysql
控制点 安全要求 要求解读 测评方法 预期结果或主要证据 身份鉴别 a)应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换 应检查MySQL数据库的口令策略配置 ...
- 在fragment中实现返回键单击提醒 双击退出
最近在练习一个小项目,也就是郭霖大神的开源天气程序,尝试用mvp架构加dagger2来重写了一下,大致功能都实现了,还没有全部完成. 项目地址 接近完成的时候,想在天气信息页面实现一个很常见的功能,也 ...
- vmware workstation导入ovf文件报错:未通过OVF规范一致性或虚拟硬件合规性检查
转自:https://blog.csdn.net/zs15yy/article/details/73793585 报错如下: 原因:这是因为OVF 版本不同导致的,VMware Workstation ...
- 【拒绝挂分】盘点蒟蒻ghy的各种sb错误
1.m与n打反(打错) NOIPd2t2 50变15爽不爽啊.jpg 某次信心赛四道sb题里面最sb的一道 sort里面的m打成n 100变40爽不爽啊.jpg(还有40我真的谢谢您了 2.没开lon ...
- 在linux中安装redis
1.安装gcc环境: yum install gcc-c++ 2.下载redis的源码包,把源码包上传到linux服务器 3.解压源码包 : tar -zxvf redis-3.0.0.tar.gz ...
- Day2-L-棋盘问题-POJ1321
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. ...
- 图论初步2<蒟蒻专属,大佬勿喷>
前言: 本节课讲的是图论的几种遍历方式,若没看图论初步1的赶紧去看 https://www.cnblogs.com/Craker/p/12271090.html 正文: 零.温故而知新 上节课我们学的 ...
- php注册与登录
一.注册 1.注册界面 <!DOCTYPE html><html lang="en"><head> <meta charset=" ...