「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)
老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次)
于是暴力啊暴力,结果我归天了。
好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党嫌丑)
那么具体除法怎么实现就是关键了
对于单个点或者区间内的数完全相同的区间,可以做成区间减法
因为除法会使数变小,而相同的数减小的量是相同的,
那么怎么判断区间内的数是否完全相同呢?
可以维护一个区间最小与区间最大,如果一个区间内最小数等于最大数,那么显然这个区间内所有数相等
区间最小与区间最大就不用说了吧?
然后暴力一波
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll sum[400101]={0}, minn[400101],maxx[400001]={0},add[400101]={0},a[401001];
int n,m;
void pushup(ll rt){
sum[rt]=sum[rt<<1|1]+sum[rt<<1];
minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);
maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]);
}
inline ll Div(ll x, ll y) {//从样例分析出这道题是向下取整的除法
return floor((double)x/y);
}
void build(ll l,ll r,ll rt){
if(l==r){
sum[rt]=a[l];
minn[rt]=a[l];
maxx[rt]=a[l];
return ;
}
long long mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
pushup(rt);
}
void pushdown(ll rt,ll ln,ll rn){
if(add[rt]!=0){
add[rt<<1]+=add[rt];
add[rt<<1|1]+=add[rt];
sum[rt<<1]+=add[rt]*ln;
sum[rt<<1|1]+=add[rt]*rn;
minn[rt<<1]+=add[rt];
minn[rt<<1|1]+=add[rt];
maxx[rt<<1]+=add[rt];
maxx[rt<<1|1]+=add[rt];
add[rt]=0;
}
}
void update1(ll l,ll r,ll c,ll L,ll R,ll rt){
if(l>=L&&r<=R){
sum[rt]+=c*(r-l+1);
add[rt]+=c;minn[rt]+=c;maxx[rt]+=c;
return ;
}
ll mid=(l+r)>>1;
pushdown(rt,mid-l+1,r-mid);
if(L<=mid)update1(l,mid,c,L,R,rt<<1);
if(R>mid)update1(mid+1,r,c,L,R,rt<<1|1);
pushup(rt);
}
void update2(ll l,ll r,ll c,ll L,ll R,ll rt){//对于除法的暴力操作
if (l >=L&&r<=R&&maxx[rt]-Div(maxx[rt],c)==minn[rt]-Div(minn[rt],c)){
ll D=Div(maxx[rt],c)-maxx[rt];
add[rt]+=D;maxx[rt]+=D;minn[rt]+=D;
sum[rt]+=D*(r-l+1);
return;
}
ll mid=(l+r)>>1;
pushdown(rt,mid-l+1,r-mid);
if(L<=mid)update2(l,mid,c,L,R,rt<<1);
if(mid<R)update2(mid+1,r,c,L,R,rt<<1|1);
pushup(rt);
}
ll query1(ll l,ll r,ll L,ll R,ll rt){
if(l>=L&&r<=R){
return sum[rt];
}
ll mid=(l+r)>>1;
ll ans=0;
pushdown(rt,mid-l+1,r-mid);
if(L<=mid)ans+=query1(l,mid,L,R,rt<<1);
if(R>mid)ans+=query1(mid+1,r,L,R,rt<<1|1);
return ans;
}
ll query2(ll l,ll r,ll L,ll R,ll rt){
if(l>=L&&r<=R){
return minn[rt];
}
ll mid=(l+r)>>1;
ll ans=1e18;
pushdown(rt,mid-l+1,r-mid);
if(L<=mid)ans=min(ans,query2(l,mid,L,R,rt<<1));
if(R>mid)ans=min(ans,query2(mid+1,r,L,R,rt<<1|1));
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)scanf("%lld",&a[i]);
//memset(flag,1,sizeof(flag));
build(0,n-1,1);
while(m--){
long long c,x,y,k;
scanf("%lld%lld%lld",&c,&x,&y);
if(c==1){scanf("%lld",&k);update1(0,n-1,k,x,y,1);}
if(c==2){scanf("%lld",&k);update2(0,n-1,k,x,y,1);}
if(c==4)printf("%lld\n",query1(0,n-1,x,y,1));
if(c==3)printf("%lld\n",query2(0,n-1,x,y,1));
}
return 0;
}
「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)的更多相关文章
- LOJ #6029. 「雅礼集训 2017 Day1」市场 线段树维护区间除法
题目描述 从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落. 有 \(n\) 个商贩,从\(0 \sim n - 1\) 编号,每个商 ...
- loj#6029. 「雅礼集训 2017 Day1」市场(线段树)
题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...
- 【loj6029】「雅礼集训 2017 Day1」市场 线段树+均摊分析
题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之 ...
- #6029. 「雅礼集训 2017 Day1」市场 [线段树]
考虑到每次除法,然后加法,差距会变小,于是维护加法lazytag即可 #include <cstdio> #include <cmath> #define int long l ...
- [LOJ 6029]「雅礼集训 2017 Day1」市场
[LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...
- 【loj6029】「雅礼集训 2017 Day1」市场&&【uoj#228】基础数据结构练习题
题解: 这两道题加上区间取min max应该算线段树几道比较不寻常的题目 其实也是挺好理解的 对于区间/d 显然在log次后就会等于0 而我们注意到如果区间中数都相等那么就可以一起除 也就是说每个区间 ...
- loj6029 「雅礼集训 2017 Day1」市场
传送门:https://loj.ac/problem/6029 [题解] 考虑如果有一些近似连续的段 比如 2 2 2 3 3 3,考虑在除3意义下,变成0 0 0 1 1 1,相当于整体-2 又:区 ...
- 【LOJ6029】「雅礼集训 2017 Day1」市场(线段树裸题)
点此看题面 大致题意: 维护序列,支持区间加法,区间除法(向下取整),区间求\(min\)和区间求和. 线段树维护区间除法 区间加法.区间求\(min\)和区间求和都是线段树基本操作,因此略过不提. ...
- 【loj6029】「雅礼集训 2017 Day1」市场
题目 题意:四种操作,区间加法.区间除法(下取整).区间求最小值.区间求和. 第1.3.4个操作都是摆设,关键在于如何做区间除法. 很明显不能直接把区间的和做除法后向下取整,因为区间和可能会多凑出一个 ...
随机推荐
- Winodws SNMP服务安装和配置(Windows 2003 & 2008 R2)
简单网络管理协议SNMP服务起着代理的作用,它会收集可以向SNMP管理站或控制台报告的信息.您可以使用SNMP服务来收集数据,并且在整个公司网络范围内管理基于Windows Server 2003.M ...
- 用js写水仙花数
...js //输入一个三位数,水仙花数就是个位的三次方+十为的三次方+百位的三次方之和等于本身 console.log('请输入一个三位数:'); let a = readline.questi ...
- windows安装的mysql中文乱码的坑
本机装的mysql为5.6的,从代码执行的中文inert语句总是显示问号,然后在中文查询是都会报问题 今天终于解决了! 问题解决方法为: 找到my.ini文件在文件中加入 [client]defaul ...
- 通用输入输出端口 - GPIO
一.概述 GPlO ( General Purpose I/0 Ports )意思为通用输入/输出端口, 通俗地说, 就是一些引脚.在芯片手册中I/O端口一般是分组的,比如有的芯片分为 A-J 共 9 ...
- Windows系统常见问题
1.Windows自动更新灰色不能修改HKEY_LOCAL_MACHINE/Software/Policies/Microsoft/WindowsWindowsUpdate的资料夹,在WindowsU ...
- jQuery中的easyui
一,easyui---datagrid绑定数据的简单测试: 1.数据库中的UserInfo表及数据测试: 2.DAL层: //分页,模糊查询(pageNum-1)*pageSize+1----从第几条 ...
- PHP获取当月天数,获取当月的每天的开始和结束的时间戳,获取当月每号
由于经常要写导单和数据分析功能,所以要获取什么时间的数据,想什么当天,周,年,月之类的时间格式都很好获取.我今天在这里为大家提供的是当月每天的开始和结束的时间格式. 希望能帮到大家!!! # 获取当月 ...
- fiddler响应报文的headers属性详解
fiddler响应报文的headers属性详解 (1)Cache头域 1. Cache-Control 在请求报文已经说过了,用于设置缓存的属性,浏览内容不被缓存. 2. Data 生成消息的具体时间 ...
- 分享一个强大的makedown编辑器
Yosoro 官网地址 https://yosoro.coolecho.net/ 很强大,支持直接粘贴图片,是直接上传到github仓库. 可直接导出md,html,pdf格式,特别方便 找了好几天的 ...
- macos 安装 brew
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" ...