题目连接:点击打开链接

从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落。

有 n nn 个商贩,从 0∼n−1 0 \sim n - 10∼n−1 编号,每个商贩的商品有一个价格 ai a_iai,有两种政令:

  1. l,r,c l, r, cl,r,c,对于 i∈[l,r],ai←ai+c i \in [l, r], a_i \leftarrow a_i + ci∈[l,r],ai←ai+c
  2. l,r,d l, r, dl,r,d,对于 i∈[l,r],ai←⌊ai/d⌋ i \in [l, r], a_i \leftarrow \lfloor {a_i}/{d} \rfloori∈[l,r],ai←⌊ai/d⌋

现在有一个外乡的旅客想要了解贸易市场的信息,有两种询问方式:

  1. 给定 l,r l, rl,r,求 mini∈[l,r]ai \min_{i \in [l, r]} a_imini∈[l,r]ai
  2. 给定 l,r l, rl,r,求 ∑i∈[l,r]ai \sum_{i\in [l, r]} a_i∑i∈[l,r]ai

Input

第一行为两个空格隔开的整数 n,q n, qn,q 分别表示商贩个数和政令 + 询问个数。
第二行包含 n nn 个由空格隔开的整数 a0∼an−1 a_0 \sim a_{n - 1}a0∼an−1
接下来 q qq 行,每行表示一个操作,第一个数表示操作编号 1∼4 1 \sim 41∼4,接下来的输入和问题描述一致。

Output

对于每个 3、4 操作,输出询问答案。

线段树的操作,有一点这题除法的时候是向下取整,当时没看见,卡了很久。

不知道为什么这种线段树总感觉怪怪的,不能真正诠释线段树这个东西,感觉在数据比较极端的情况下会超时。

哎,可能是因为我太菜了,没能理解。。。

首先这里有一个向下取整的操作,就很烦。那么我们把除法变成减法的操作就简单了,但必须是区间内所有的数减的是一样的。

那咋办,,判断最大的数需要减多少盒最小的数需要减多少,如果一样的话就用区间更新的操作,如果不一样那就继续搜。。

还有一点就是负数和非负数要分情况讨论,其他也就没什么了。。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100010;
const ll inf=1e18;
ll sum[maxn<<2],lazy[maxn<<2];
ll d[maxn<<2],x[maxn<<2];
void up(int root)
{sum[root]=sum[root<<1]+sum[root<<1|1];d[root]=max(d[root<<1],d[root<<1|1]);x[root]=min(x[root<<1],x[root<<1|1]);return;
}
void down(int root,int l,int r)
{lazy[root<<1]+=lazy[root];lazy[root<<1|1]+=lazy[root];int mid=(l+r)/2;sum[root<<1]+=(mid-l+1)*lazy[root];sum[root<<1|1]+=(r-mid)*lazy[root];x[root<<1]+=lazy[root];x[root<<1|1]+=lazy[root];d[root<<1]+=lazy[root];d[root<<1|1]+=lazy[root];lazy[root]=0;
}
void build(int root,int l,int r)
{lazy[root]=0;if(l==r){scanf("%lld",&sum[root]);d[root]=x[root]=sum[root];return;}int mid=(l+r)/2;build(root<<1,l,mid);build(root<<1|1,mid+1,r);up(root);
}
void updata1(int root,int nowa,int nowb,int l,int r,int val)
{if(nowb<l||r<nowa) return;if(l<=nowa&&nowb<=r){sum[root]+=(nowb-nowa+1)*val;d[root]+=val;x[root]+=val;lazy[root]+=val;return;}if(lazy[root]) down(root,nowa,nowb);int mid=(nowa+nowb)/2;updata1(root<<1,nowa,mid,l,r,val);updata1(root<<1|1,mid+1,nowb,l,r,val);up(root);
}
void updata2(int root,int nowa,int nowb,int l,int r,int val)
{if(nowb<l||r<nowa) return;if(l<=nowa&&nowb<=r){ll X,Y;if (x[root]>=0) X=x[root]/val;else X=(x[root]-val+1)/val;if (d[root]>=0) Y=d[root]/val;else Y=(d[root]-val+1)/val;if (X-x[root]==Y-d[root]){lazy[root]+=X-x[root];sum[root]+=(X-x[root])*(nowb-nowa+1);d[root]+=X-x[root];x[root]+=X-x[root];return ;}}if(lazy[root]) down(root,nowa,nowb);int mid=(nowa+nowb)/2;updata2(root<<1,nowa,mid,l,r,val);updata2(root<<1|1,mid+1,nowb,l,r,val);up(root);
}
ll query1(int root,int nowa,int nowb,int l,int r)
{if(nowb<l||r<nowa) return 0;if(l<=nowa&&nowb<=r) return sum[root];if(lazy[root]) down(root,nowa,nowb);int mid=(nowa+nowb)/2;ll ans=0;ans+=query1(root<<1,nowa,mid,l,r);ans+=query1(root<<1|1,mid+1,nowb,l,r);up(root);return ans;
}
ll query2(int root,int nowa,int nowb,int l,int r)
{if(nowb<l||r<nowa) return inf;if(l<=nowa&&nowb<=r) return x[root];if(lazy[root]) down(root,nowa,nowb);int mid=(nowa+nowb)/2;ll ans=inf;ans=min(ans,query2(root<<1,nowa,mid,l,r));ans=min(ans,query2(root<<1|1,mid+1,nowb,l,r));up(root);return ans;
}
int main()
{int n,q,op,x,y,z;scanf("%d%d",&n,&q);build(1,0,n-1);while(q--){scanf("%d",&op);if(op==1){scanf("%d%d%d",&x,&y,&z);updata1(1,0,n-1,x,y,z);}else if(op==2){scanf("%d%d%d",&x,&y,&z);updata2(1,0,n-1,x,y,z);}else if(op==3){scanf("%d%d",&x,&y);printf("%lld\n",query2(1,0,n-1,x,y));}else{scanf("%d%d",&x,&y);printf("%lld\n",query1(1,0,n-1,x,y));}}return 0;
}

ZCUM-1948: #6029. 「雅礼集训 2017 Day1」市场 线段树区间更新相关推荐

  1. 【loj6029】「雅礼集训 2017 Day1」市场 线段树+均摊分析

    题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之 ...

  2. #6029. 「雅礼集训 2017 Day1」市场(势能,区间除)

    #6029. 「雅礼集训 2017 Day1」市场 用线段树维护数列,区间上维护最大最小值,区间和还有标记,修改时,区间加直接做,而区间除时,递归到线段树上某一区间,如果这一操作等价于区间加(也就是最 ...

  3. 数据结构二之线段树Ⅱ——KiKi‘s K-Number,ball,The Child and Sequence,「雅礼集训 2017 Day1」市场,Atlantis

    值域线段树+势能线段树+扫描线 KiKi's K-Number ball The Child and Sequence 「雅礼集训 2017 Day1」市场 Atlantis KiKi's K-Num ...

  4. LibreOJ#6030. 「雅礼集训 2017 Day1」矩阵

    https://loj.ac/problem/6030 如果矩阵第i列有一个黑色, 那可以用他把第i行全都染黑,也可以使任意一列具有黑色 然后就可以用第i行把矩阵染黑 染黑一列的代价最少是1 染黑一行 ...

  5. [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)

    [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相 description solution 一个到所有节点距离和最小的节点 ⇔\Leftrightarrow⇔ 树的重心(满足最重的儿 ...

  6. #6034. 「雅礼集训 2017 Day2」线段游戏 李超树

    #6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统 ...

  7. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 -- 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

  8. LOJ#6044. 「雅礼集训 2017 Day8」共(Prufer序列)

    题面 传送门 题解 答案就是\(S(n-k,k)\times {n-1\choose k-1}\) 其中\(S(n,m)\)表示左边\(n\)个点,右边\(m\)个点的完全二分图的生成树个数,它的值为 ...

  9. LOJ#6048. 「雅礼集训 2017 Day10」数列(线段树)

    题面 传送门 题解 我的做法似乎非常复杂啊-- 首先最长上升子序列长度就等于把它反过来再接到前面求一遍,比方说把\(2134\)变成\(43122134\),实际上变化之后的求一个最长上升子序列和方案 ...

最新文章

  1. 【AI】caffe使用步骤(一):将标注数据生成lmdb或leveldb
  2. Dubbo配置文件详解
  3. 如何从菜鸡变成收割机,大厂面试的算法,你懂了吗?
  4. linux boot空间分多少,/boot分区空间不足,清理老内核所占空间
  5. 收藏一个有趣的帖子,现在的客户端真有点让人不安,难怪XSS。。。
  6. Wooden Sticks POJ - 1065(最大上升子序列+动态规划状态转移思维)
  7. threadlocal_了解ThreadLocal背后的概念
  8. java面试宝典 多线程,《java面试宝典》之java多线程面试题
  9. 关于Java String对象创建问题解惑
  10. Open3d之计算源点云与目标云的距离
  11. 能被2、3、4、5、6、7、8、9、10、11、13、25整除的整数的特征是?有趣的21详解
  12. JavaScript学习笔记——对表单的操作
  13. 美联储加息已成“政治正确” 美元涨势难以阻挡?
  14. 「微信同声传译」小程序插件:快速实现语音转文字、文本翻译、语音合成等能力
  15. Codingame平台“CHUCK NORRIS”的实现
  16. 读书笔记:重来 Rework
  17. Photoshop辅助线和标尺的使用技巧
  18. java计算机毕业设计教师管理系统源码+mysql数据库+系统+lw文档+部署
  19. java 基础运算_Java 基础 运算符
  20. 洁净室环境在线式监测实时读取颗粒尘埃粒子计数器

热门文章

  1. python统计英文文章中单词出现的次数
  2. linux系统下深度学习环境搭建和使用
  3. 谷歌浏览器打开本地堡垒机应用发布服务器cmd的方法
  4. 前后台订单入库调用流程
  5. echarts地图 自定义区域
  6. AWS免费云主机之如何使用putty登录
  7. Android GPS定位记录发送功能
  8. 数博会金蝶揭秘智能零售:名企转型底气
  9. idea列模式按列选取代码或按行选取代码快捷键
  10. vue系列教程之微商城项目|项目创建