【loj6029】「雅礼集训 2017 Day1」市场
题意:四种操作,区间加法、区间除法(下取整)、区间求最小值、区间求和。
第1、3、4个操作都是摆设,关键在于如何做区间除法。
很明显不能直接把区间的和做除法后向下取整,因为区间和可能会多凑出一个除数因子。例如$3,3$,对这两个数的区间除以2取整后变成$1,1$,但如果直接把它们的和6除以2取整后得到的和是3,很明显有误。
但是根据经验,带有区间除法操作的题目一般都会把数给你往小了压。再一看这题,两个修改操作中,区间加法的加数不大且可能是负数,而除数可高达$10^9$!
尤其是除法的大除数带来的影响特别大,这实际上暗示我们序列的数很容易迅速被压到0附近。而数的绝对值被压到很小,除数却有很大时,我们发现实际上这些数的变化可能会很小。小到什么程度呢?
考虑如果有一些近似连续的小数段,
比如$2,2,2,3,3,3$,在除3意义下,变成$0,0,0,1,1,1$,相当于整体-2。
在序列的数都被压到足够接近0时,很容易出现上面这种序列,此时就可以用区间加法维护上面这种区间的除法操作了!
那怎么判断除法区间的所有数的变化量是否相同呢?只需判断最大值和最小值的变化量是否相同即可。原因:除法区间的数按从小到大的顺序,数的变化量是单调不下降的(大数和小数都被同一个大于等于$1$的正数(题目说了除数在$[2,10^9]$范围内)除,大数当然还比小数大,变化量也比小数大,即使是在向下取整的意义下,大数仍不会比小数小,变化量也不会比小数小(为什么除数是在$(0,1)$范围内的正数时 "变化量也不会比小数小" 这条不成立,请自行思考,如果想明白了你也就明白为什么除数是大于等于$1$的正数时这条成立了)),所以只要看两端的最小值和最大值的变化量是否相同就能知道整个区间的数的变化量是否相同。
归根结底区间除法转化成了区间加法+区间最大值+区间最小值,于是还需要维护一下原题没有要求的区间最大值。
#include<bits/stdc++.h>
#define N 100001
#define inf 0x7f7f7f7f7f7f7f7f
using namespace std;
inline int read(){
int x=; bool f=; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=;
for(; isdigit(c);c=getchar()) x=(x<<)+(x<<)+(c^'');
if(f) return x;
return -x;
}
int n,q;
long long a[N],mx[N<<],mn[N<<],sum[N<<],tag[N<<];
int L,R,x;
inline void pushup(int o){
sum[o]=sum[o<<]+sum[o<<|];
mx[o]=max(mx[o<<],mx[o<<|]);
mn[o]=min(mn[o<<],mn[o<<|]);
}
void pushdown(int o,int l,int r){
if(!tag[o] || l==r) return;
//printf("pushdown:%d %d %d %d %d\n",o,l,r,tag[o],mn[o]);
int mid=(l+r)>>;
sum[o<<]+=(mid-l+)*tag[o], sum[o<<|]+=(r-mid)*tag[o];
mx[o<<]+=tag[o], mx[o<<|]+=tag[o];
mn[o<<]+=tag[o], mn[o<<|]+=tag[o];
tag[o<<]+=tag[o], tag[o<<|]+=tag[o]; //严重错因,好几个小时才查出这里直接覆盖儿子tag值的错误,一定要铭记!
tag[o]=;
}
void build(int o,int l,int r){
//printf("%d %d %d\n",o,l,r); system("pause");
if(l==r){sum[o]=mx[o]=mn[o]=a[l]; return;}
int mid=(l+r)>>;
build(o<<,l,mid), build(o<<|,mid+,r);
pushup(o);
}
void add(int o,int l,int r){
//printf("query:%d %d %d %d\n",l,r,mn[o],tag[o]);
if(L<=l && r<=R){
tag[o]+=x, sum[o]+=(long long)(r-l+)*x, mx[o]+=x, mn[o]+=x;
return;
}
pushdown(o,l,r);
int mid=(l+r)>>;
if(L<=mid) add(o<<,l,mid);
if(mid<R) add(o<<|,mid+,r);
pushup(o);//printf("pushup hou:%d %d %d %d %d\n",l,r,mn[o],mn[o<<1],mn[o<<1|1]);
}
long long min_query(int o,int l,int r){
//printf("query:%d %d %d %d\n",l,r,mn[o],tag[o]);
if(L<=l && r<=R) return mn[o];
pushdown(o,l,r);
int mid=(l+r)>>;
long long ret=inf;
if(L<=mid) ret=min(ret,min_query(o<<,l,mid));
if(mid<R) ret=min(ret,min_query(o<<|,mid+,r));
pushup(o);
return ret;
}
void div(int o,int l,int r){
//printf("query:%d %d %d %d\n",l,r,mn[o],tag[o]);
if(L<=l && r<=R){
long long g1=mx[o]-(long long)floor((double)mx[o]/x), g2=mn[o]-(long long)floor((double)mn[o]/x);
if(g1==g2){
//printf("fvcking subquence:%d %d %lld %lld\n",l,r,g1,g2);
tag[o]-=g1, sum[o]-=(r-l+)*g1, mx[o]-=g1, mn[o]-=g1;
return;
}
}
pushdown(o,l,r);
int mid=(l+r)>>;
if(L<=mid) div(o<<,l,mid);
if(mid<R) div(o<<|,mid+,r);
pushup(o);
}
long long sum_query(int o,int l,int r){
//printf("query:%d %d %d %d\n",l,r,mn[o],tag[o]);
if(L<=l && r<=R) return sum[o];
pushdown(o,l,r);
int mid=(l+r)>>;
long long ret=;
if(L<=mid) ret+=sum_query(o<<,l,mid);
if(mid<R) ret+=sum_query(o<<|,mid+,r);
pushup(o);
return ret;
} void find(int o,int l,int r){
if(l==r){printf("%d ",sum[o]); return;}
pushdown(o,l,r);
int mid=(l+r)>>;
find(o<<,l,mid), find(o<<|,mid+,r);
pushup(o);
} int main(){
//freopen("rand.in","r",stdin);
//freopen("count.out","w",stdout);
n=read(),q=read();
int i,k;
for(i=;i<=n;i++) a[i]=read();
build(,,n);
for(i=;i<=q;i++){
k=read(),L=read()+,R=read()+;
if(k==) x=read(), add(,,n);
else if(k==) x=read(), div(,,n);
else if(k==) printf("%lld\n",min_query(,,n));
else if(k==) printf("%lld\n",sum_query(,,n));
//find(1,1,n);
//putchar('\n');putchar('\n');putchar('\n');putchar('\n');
}
return ;
}
/*
10 11
1 2 3 4 5 6 7 8 9 10
2 0 9 2
2 0 9 3
2 0 9 4
2 0 9 5
2 0 9 6
3 0 9
4 0 9
1 0 4 -4
2 0 4 2
3 0 4
4 0 9
*/
【loj6029】「雅礼集训 2017 Day1」市场的更多相关文章
- 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」市场 (线段树)
题面 从前有一个学校,在 O n e I n D a r k \rm OneInDark OneInDark 到任之前风气都是非常良好的,自从他来了之后,发布了一系列奇怪的要求,挟制了整个学校,导致风 ...
- [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」市场 线段树+均摊分析
题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之 ...
- 【LOJ6029】「雅礼集训 2017 Day1」市场(线段树裸题)
点此看题面 大致题意: 维护序列,支持区间加法,区间除法(向下取整),区间求\(min\)和区间求和. 线段树维护区间除法 区间加法.区间求\(min\)和区间求和都是线段树基本操作,因此略过不提. ...
- loj#6029. 「雅礼集训 2017 Day1」市场(线段树)
题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...
- 「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)
老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次) 于是暴力啊暴力,结果我归天了. 好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党 ...
- #6029. 「雅礼集训 2017 Day1」市场 [线段树]
考虑到每次除法,然后加法,差距会变小,于是维护加法lazytag即可 #include <cstdio> #include <cmath> #define int long l ...
随机推荐
- 你不知道的HTTP之HTTPS
确保web安全的HTTPS HTTPS=HTTP+ 加密 + 认证 + 完整性保护 1.加密: 1)通信的加密 所谓互联网,是由能连通到全世界的网络组成的.无论世界哪个角 落的服务器在和客户端通信时, ...
- Android学习总结(二)——Service基本概念和生命周期
好了,前面我们已经学习了Activity的知识,相信大家也有一定的理解,但是还是不能放松,Android四大组件,我们才学习了一个而已,接下我们继续学习Service.计划总结如下内容: 一.Serv ...
- vijos 1448 校门外的树 (不是05年普及组那题)
描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:K=1,K=1,读入l.r表 ...
- 文字自动自左向右滚动的js代码
重要的一点,就是scrollLeft一直在变化.对象一直在移动,参照物没有动. 代码: css: #div1{display:black;width:110px;height:50px;line-he ...
- HDU 6052 To my boyfriend(容斥+单调栈)
题意:对于一个n*m的方格,每个格子中都包含一种颜色,求出任意一个矩形包含不同颜色的期望. 思路: 啊啊啊啊啊,补了两天,总算A了这道题了,简直石乐志,前面的容斥还比较好写,后面的那个>13那个 ...
- java在线聊天项目0.6版 解决客户端关闭后异常问题 dis.readUTF()循环读取已关闭的socket
服务端对try catch finally重新进行了定义,当发生异常,主动提示,或关闭出现异常的socket 服务器端代码修改如下: package com.swift; import java.io ...
- 【NOIP2017提高A组冲刺11.6】拆网线
和syq大兄弟吐槽题目不小心yy出了正解.. 最优的选法就是选两个两个相互独立的,欸这不就是最大匹配吗?那多的企鹅就新加一条边呗?不够的就除以2上取整呗? 欸?AC了? 树也是一个二分图,最大匹配=最 ...
- (39)zabbix snmp自定义OID nginx监控实例
为什么要自定义OID? 前面的文章已经讲过zabbix如何使用snmp监控服务器,但是他有一个很明显的局限性:只能监控定义好的OID项目 假如我们想知道nginx进程是否在运行?在没有zabbix a ...
- (31)zabbix Aggregate checks聚合检测
概述 aggregate checks是一个聚合的检测,例如我想知道某个组的host负载平均值,硬盘剩余总量,或者某几台机器的这些数据,简单的说,这个方法就是用来了解一个整体水平,而不需要我们一台台看 ...
- Mac OSX: 有线共享WiFi
首先连上有线 系统偏好设置->网络->点击左侧WiFi,再点击右下角[高级] 勾选[创建电脑对电脑网络],然后单击[好] 在顶部菜单栏击WiFi图标,如果WiFi未打开,则单击打开,如果已 ...