[雅礼集训 2017 Day1]市场
试题分析
可以容易发现此题维护的是一个数据结构,支持区间加,区间除,区间查询最大值。其实就是在$\log$级复杂度内维护除法操作。
我们发现当除数很大或者此串序列大小差不多时,我们令$a_i$为原来,$b_i$为现在,则对于$[l,r]$中的任意一个数$i$,则出现$a_i-b_i$为恒值。则我们可以用线段树去维护即可。
举个例子:
当我们要在$1,2,3,4,5$中每一个数除以$1$时,我们可以发现每个数都$a_i-b_i=0$,所以做区间减法即可
当我们要在$2,3,3,3,3$中每一个数除以$2$时,$a_i-b_i=2$.所以此段区间每个数减$2$即可。
那我们则么快速寻找是否会一样,我们只要看一下当前序列最大值与最小值的变化即可,因为他们是具有代表性的。
然后就只要维护一个区间修改,最大值,最小值,区间查询的线段树即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<climits>
#define int long long
using namespace std;
inline int read()
{
int f=,ans=;char c;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){ans=ans*+c-'';c=getchar();}
return ans*f;
}
const int N=;
int n,q;
int val[N],maxn[N<<],minn[N<<],sum[N<<],tag[N<<];
void pushup(int k){
maxn[k]=max(maxn[k<<],maxn[k<<|]);
minn[k]=min(minn[k<<],minn[k<<|]);
sum[k]=sum[k<<]+sum[k<<|];
}
void build(int k,int l,int r){
if(l==r){maxn[k]=minn[k]=sum[k]=val[l];return;}
int mid=l+r>>;
build(k<<,l,mid),build(k<<|,mid+,r);
pushup(k);
return;
}
void pushdown(int k,int l,int r){
if(tag[k]==) return;
int mid=l+r>>;
sum[k<<]+=(mid-l+)*tag[k],sum[k<<|]+=(r-mid)*tag[k];
maxn[k<<]+=tag[k],minn[k<<]+=tag[k];
maxn[k<<|]+=tag[k],minn[k<<|]+=tag[k];
tag[k<<]+=tag[k],tag[k<<|]+=tag[k];
tag[k]=;
return;
}
void add(int k,int l,int r,int x,int y,int w){
// cout<<"l:"<<l<<" r:"<<r<<" w:"<<w<<endl;
if(x<=l&&r<=y){
maxn[k]+=w,minn[k]+=w,tag[k]+=w;sum[k]+=(r-l+)*w;
return;
}
pushdown(k,l,r);
int mid=l+r>>;
if(x<=mid) add(k<<,l,mid,x,y,w);
if(mid<y) add(k<<|,mid+,r,x,y,w);
pushup(k);
return;
}
void div(int k,int l,int r,int x,int y,int w){
if(x<=l&&r<=y){
int s1=maxn[k]-(int)floor((double)maxn[k]/(double)w),s2=minn[k]-(int)floor((double)minn[k]/(double)w);
if(s1==s2){
tag[k]-=s1;sum[k]-=(r-l+)*s1;maxn[k]-=s1,minn[k]-=s1;
return;
}
}
pushdown(k,l,r);
int mid=l+r>>;
if(x<=mid) div(k<<,l,mid,x,y,w);
if(mid<y) div(k<<|,mid+,r,x,y,w);
pushup(k);
return;
}
int query_minn(int k,int l,int r,int x,int y){
if(x<=l&&r<=y) return minn[k];
int res=LLONG_MAX,mid=l+r>>;
pushdown(k,l,r);
if(x<=mid) res=min(res,query_minn(k<<,l,mid,x,y));
if(mid<y) res=min(res,query_minn(k<<|,mid+,r,x,y));
pushup(k);
return res;
}
int query_sum(int k,int l,int r,int x,int y){
if(x<=l&&r<=y) return sum[k];
pushdown(k,l,r);
int res=,mid=l+r>>;
if(x<=mid) res+=query_sum(k<<,l,mid,x,y);
if(mid<y) res+=query_sum(k<<|,mid+,r,x,y);
pushup(k);
return res;
}
void find1(int k,int l,int r){
if(l==r){cout<<maxn[k]<<" ";return;}
int mid=l+r>>;
pushdown(k,l,r);
find1(k<<,l,mid),find1(k<<|,mid+,r);
pushup(k);
return;
}
signed main(){
n=read(),q=read();
for(int i=;i<=n;i++) val[i]=read();
build(,,n);
while(q--){
int opt=read(),l=read()+,r=read()+;
if(opt==) {
int w=read();
add(,,n,l,r,w);
}
if(opt==){
int w=read();
div(,,n,l,r,w);
}
if(opt==) printf("%lld\n",query_minn(,,n,l,r));
if(opt==) printf("%lld\n",query_sum(,,n,l,r));
}
}
[雅礼集训 2017 Day1]市场的更多相关文章
- [LOJ 6029]「雅礼集训 2017 Day1」市场
[LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...
- 「雅礼集训 2017 Day1」 解题报告
「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...
- [LOJ 6031]「雅礼集训 2017 Day1」字符串
[LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询 ...
- [LOJ 6030]「雅礼集训 2017 Day1」矩阵
[LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解 ...
- loj#6029. 「雅礼集训 2017 Day1」市场(线段树)
题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...
- 【loj6029】「雅礼集训 2017 Day1」市场&&【uoj#228】基础数据结构练习题
题解: 这两道题加上区间取min max应该算线段树几道比较不寻常的题目 其实也是挺好理解的 对于区间/d 显然在log次后就会等于0 而我们注意到如果区间中数都相等那么就可以一起除 也就是说每个区间 ...
- 【loj6029】「雅礼集训 2017 Day1」市场 线段树+均摊分析
题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之 ...
- 「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)
老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次) 于是暴力啊暴力,结果我归天了. 好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党 ...
- loj6029 「雅礼集训 2017 Day1」市场
传送门:https://loj.ac/problem/6029 [题解] 考虑如果有一些近似连续的段 比如 2 2 2 3 3 3,考虑在除3意义下,变成0 0 0 1 1 1,相当于整体-2 又:区 ...
随机推荐
- arduino蜂鸣器的使用
一:蜂鸣器的使用 控制要求:模拟救护车响声 实物连接图: 电路原理图: 控制代码: //智慧自动化2018.6.11 ;//设置控制蜂鸣器的数字IO脚 void setup() { pinMode(b ...
- 用MYSQLworkbench导出数据excel
步骤: 1.先从数据库中将表导出,右键需要导出的表格——>Table Data Export Wizard 2.点击Next,选择你需要把数据存放的文件路径.导出的数据格式(表格的话就默认选择C ...
- Animator & Timeline
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Pla ...
- EasyUI validatebox 自定义ajax验证用户名是否已存在
<td><input type="text" id="userName" name="userName" class=&q ...
- 7个Node.js的Web框架
NodeJS也就是Node,是众所周知的使用javascript构建Web应用框架,它启动一个服务器非常简单,如下: var http = require('http'); http.createSe ...
- HTML5+Bootstrap 学习笔记 2
navbar升级 从Bootstrap 2到Bootstrap 3 1. .navbar-inner已从Bootstrap 3中去除. 2. <ul class="nav"& ...
- 论文爬取 & 词频统计2.0
一.Github地址 课程项目要求 队友博客 二.具体分工 031602225 林煌伟 :负责C++部分主要功能函数的编写,算法的设计以及改进优化 031602230 卢恺翔 : 爬虫 ...
- [转]Android试验:如果View的ID相同会出现什么效果?
1.实验:通过布局编辑器强行指定两个button id相同,然后在代码中通过findViewById()获得句柄后修改其文本. 实验结果:只有一个button的文本变化了,另一个不受影响. 2.实 ...
- Codeforces Round #272 (Div. 2) E. Dreamoon and Strings dp
题目链接: http://www.codeforces.com/contest/476/problem/E E. Dreamoon and Strings time limit per test 1 ...
- prototype.js中Function.prototype.bind方法浅解
prototype.js中的Function.prototype.bind方法: Function.prototype.bind = function() { var __method = this; ...