老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有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」市场 (线段树除法,区间最小,区间查询)的更多相关文章

  1. LOJ #6029. 「雅礼集训 2017 Day1」市场 线段树维护区间除法

    题目描述 从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落. 有 \(n\) 个商贩,从\(0 \sim n - 1\) 编号,每个商 ...

  2. loj#6029. 「雅礼集训 2017 Day1」市场(线段树)

    题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...

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

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

  4. #6029. 「雅礼集训 2017 Day1」市场 [线段树]

    考虑到每次除法,然后加法,差距会变小,于是维护加法lazytag即可 #include <cstdio> #include <cmath> #define int long l ...

  5. [LOJ 6029]「雅礼集训 2017 Day1」市场

    [LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...

  6. 【loj6029】「雅礼集训 2017 Day1」市场&&【uoj#228】基础数据结构练习题

    题解: 这两道题加上区间取min max应该算线段树几道比较不寻常的题目 其实也是挺好理解的 对于区间/d 显然在log次后就会等于0 而我们注意到如果区间中数都相等那么就可以一起除 也就是说每个区间 ...

  7. loj6029 「雅礼集训 2017 Day1」市场

    传送门:https://loj.ac/problem/6029 [题解] 考虑如果有一些近似连续的段 比如 2 2 2 3 3 3,考虑在除3意义下,变成0 0 0 1 1 1,相当于整体-2 又:区 ...

  8. 【LOJ6029】「雅礼集训 2017 Day1」市场(线段树裸题)

    点此看题面 大致题意: 维护序列,支持区间加法,区间除法(向下取整),区间求\(min\)和区间求和. 线段树维护区间除法 区间加法.区间求\(min\)和区间求和都是线段树基本操作,因此略过不提. ...

  9. 【loj6029】「雅礼集训 2017 Day1」市场

    题目 题意:四种操作,区间加法.区间除法(下取整).区间求最小值.区间求和. 第1.3.4个操作都是摆设,关键在于如何做区间除法. 很明显不能直接把区间的和做除法后向下取整,因为区间和可能会多凑出一个 ...

随机推荐

  1. C/C++ Windows API——获取计算机信息 转

    转自:http://blog.csdn.net/chy555chy/article 函数 头文件 作用 GetVersionEx <windows.h> 获取系统版本信息(deprecat ...

  2. javaScript 工作必知(十一) 数组常用方法实现

    大纲 Array join reverse反转 sort排序 concat 拼接 slice splice 数组 //定义数组 var a = []; //使用Array定义一个数组, var a1 ...

  3. STM32之定时器输入捕获

    1.输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能.STM32的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿 ...

  4. Mybatis 原始dao CRUD方法

    用到的相关jar包及所用版本如下: 其中的Mybatis可以到github.com的网站下载 <project xmlns="http://maven.apache.org/POM/4 ...

  5. CSS之元素

    CSSS书写位置 内嵌式 <head> <style type = "text/css"> **** </style> </head> ...

  6. c#数据库访问服务(综合数据库操作)

    前面给大家说封装了常用的数据库,并且整理了使用.最近我再次把项目整合了.做成比较完善的服务. 还是重复的说下数据库操作封装. berkeley db数据库,Redis数据库,sqlite数据库. 每个 ...

  7. 关于gitbash一直报:sh: __git_ps1: command not found的解决办法

    curl -o ~/.git-prompt.sh https://raw.githubusercontent.com/git/git/master/contrib/completion/git-pro ...

  8. Django学习笔记4-csrf防护

    1.CSRF验证失败. 请求被中断. 原因是django为了在用户提交表单时防止跨站攻击所做的保护 什么是 CSRF CSRF, Cross Site Request Forgery, 跨站点伪造请求 ...

  9. 转:30分钟了解Springboot整合Shiro

    引自:30分钟了解Springboot整合Shiro 前言:06年7月的某日,不才创作了一篇题为<30分钟学会如何使用Shiro>的文章.不在意之间居然斩获了22万的阅读量,许多人因此加了 ...

  10. C#获取本地磁盘信息

    直接上干货简单易懂 //磁盘监控(远程/本地) //需要引用System.Management.dll public class RemoteMonitoring { private static s ...