Description

小Z经营一家加油店。小Z加油的方式非常奇怪。他有一排瓶子,每个瓶子有一个容量vi。每次别人来加油,他会让
别人选连续一段的瓶子。他可以用这些瓶子装汽油,但他只有三种操作:
1.把一个瓶子完全加满;
2.把一个瓶子完全倒空;
3.把一个瓶子里的汽油倒进另一个瓶子,直到倒出瓶子空了或者倒进的瓶子满了。
当然,为了回馈用户,小Z会时不时选择连续一段瓶子,给每个瓶子容积都增加x。
为了尽可能给更多的人加油,每次客户来加油他都想知道他能够倒腾出的汽油量最少是多少?
当然他不会一点汽油都不给客户。

Input

第一行包括两个数字:瓶子数n,事件数m。
第二行包含n个整数,表示每个瓶子的容量vi。
接下来m行,每行先有三个整数fi li ri。
若fi=1表示询问li到ri他最少能倒腾出的汽油量最少是多少?
若fi=2 再读入一个整数x。表示他将li到ri的瓶子容量都增加了x。
1 <= n,m <= 10^5 , 1<=li<=ri<=n , 1<=初始容量,增加的容量<=1000

Output

对于每个询问输出对应的答案

Sample Input

3 4
2 3 4
1 1 3
2 2 2 1
1 1 3
1 2 3

Sample Output

1
2
4

HINT

有可能出现L>R

——————————————————————————————

考虑一下更相减损术 题目就转换成了求区间gcd(带修改

这是一波套路题 考虑gcd(a,b,c,d,e)=gcd(a-b,b-c,c-d,d-e,e)

所以我们可以维护一下差分 也就是类似a-b这样的东西

这样之后区间l->r +v 就变成了 l-1 - v  r +v

当然注意最后的e是不带差分的 所以还要维护一下原序列 方便查询右端点r

所以需要的操作就是 维护原序列的差分(单点修改区间查gcd)和原序列本身(区间加单点查询)

#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=1e5+;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,m,p;
int N,g[*M],bit[M],h[M];
int gcd(int x,int y){
while(y){p=x%y; x=y; y=p;}
return x;
}
void tr_modify(int x,int v){
g[x+=N]+=v;
for(x>>=;x;x>>=) g[x]=gcd(g[x<<],g[x<<^]);
}
#define lowbit(x) x&-x
int s[M];
void bit_insert(int x,int v){
while(x<=n){
s[x]+=v;
x+=lowbit(x);
}
}
int bit_query(int x){
int ans=h[x];
while(x) ans+=s[x],x-=lowbit(x);
return ans;
}
void modify(int l,int r,int v){
bit_insert(l,v); tr_modify(l-,-v);
bit_insert(r+,-v); tr_modify(r,v);
}
int push_ans(int l,int r){
int ans=bit_query(r);
for(l=l+N-,r=r+N;r-l!=;l>>=,r>>=){
if(~l&) ans=gcd(ans,g[l^]);
if(r&) ans=gcd(ans,g[r^]);
}
if(ans<) ans=-ans;
return ans;
}
void pd(int &x,int &y){if(x>y) std::swap(x,y);}
int main(){
int k,l,r,v;
n=read(); m=read();
for(int i=;i<=n;i++) h[i]=read();
for(N=;N<=n+;N<<=);
for(int i=;i<n;i++) g[i+N]=h[i]-h[i+];
for(int i=N-;i;i--) g[i]=gcd(g[i<<],g[i<<^]);
for(int i=;i<=m;i++){
k=read();
if(k==) l=read(),r=read(),pd(l,r),printf("%d\n",push_ans(l,r));
else l=read(),r=read(),v=read(),pd(l,r),modify(l,r,v);
}
return ;
}

bzoj 5028: 小Z的加油店——带修改的区间gcd的更多相关文章

  1. BZOJ 5028 小Z的加油店

    [题解] 本题要求求出区间内的各个元素通过加减之后能够得出的最小的数,那么根据裴蜀定理可知答案就是区间内各个元素的最大公约数. 那么本题题意化简成了维护一个序列,支持区间加上某个数以及查询区间元素的最 ...

  2. 5028: 小Z的加油店(线段树)

    NOI2012魔幻棋盘弱化版 gcd(a,b,c,d,e)=gcd(a,b-a,c-b,d-c,e-d) 然后就可以把区间修改变成差分后的点修了. 用BIT维护原序列,线段树维护区间gcd,支持点修区 ...

  3. 【BZOJ】5028: 小Z的加油店

    [算法]数学+线段树/树状数组 [题解] 首先三个操作可以理解为更相减损术或者辗转相除法(待证明),所以就是求区间gcd. 这题的问题在线段树维护gcd只能支持修改成一个数,不支持加一个数. 套路:g ...

  4. BZOJ 5028 小z的加油站

    bzoj链接 Time limit 10000 ms Memory limit 262144 kB OS Linux 感想 树上动态gcd的第二题也好了. [x] BZOJ 2257 [JSOI200 ...

  5. D - 小Z的加油店 线段树+差分+GCD

    D - 小Z的加油店 HYSBZ - 5028   这个题目是一个线段树+差分+GCD 推荐一个差分的博客:https://www.cnblogs.com/cjoierljl/p/8728110.ht ...

  6. [BZOJ5028]小Z的加油店

    [BZOJ5028]小Z的加油店 题目大意: 一个长度为\(n(n\le10^5)\)的数列,\(m(m\le10^5)\)次操作,支持区间加和区间\(\gcd\). 思路: 线段树维护差分,\(\g ...

  7. bzoj5028小Z的加油店(线段树+差分)

    题意:维护支持以下两种操作的序列:1 l r询问a[l...r]的gcd,2 l r x把a[l...r]全部+x 题解:一道经典题.根据gcd(a,b)=gcd(a-b,b)以及区间加可知,这题可以 ...

  8. 【bzoj5028】小Z的加油店 扩展裴蜀定理+差分+线段树

    题目描述 给出 $n$ 个瓶子和无限的水,每个瓶子有一定的容量.每次你可以将一个瓶子装满水,或将A瓶子内的水倒入B瓶子中直到A倒空或B倒满.$m$ 次操作,每次给 $[l,r]$ 内的瓶子容量增加 $ ...

  9. bzoj 4031: 小Z的房间 矩阵树定理

    bzoj 4031: 小Z的房间 矩阵树定理 题目: 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时 ...

随机推荐

  1. java冒泡算法

    public static void maopao() { int temp; int[] values = {2, 34, 0, 245}; for (int i = 0; i < value ...

  2. 2016.01.04接触spring一年开始读spring源码

    http://www.cnblogs.com/xing901022/p/4178963.html#_label0 遇到第一个问题The processing instruction target ma ...

  3. 白话HMM系列1——从一个缩略语还原的例子说起

    HMM到底是一个什么样的东西,我想从我研究的一个应用场景开始说起.之所以想重新描述一下我对HMM的理解,是因为上次面试百度糯米的时候,自己没有把HMM在应用上说的很明白,不过糯米的那位郑姓面试官我也是 ...

  4. 【个人训练】(UVa146)ID Codes

    题意与解析 这题其实特别简单,求给定排列的后继.使用stl(next_permutation)可以方便地解决这个问题.但是,想要自己动手解就是另外一回事了.我的解法是从后往前找到第一个$a_i$比$a ...

  5. Selenide 简单实现自动化测试

    Selenide 网址:http://selenide.org/ github 地址:https://github.com/codeborne/selenide Selenide 早些年一直使用,中间 ...

  6. (原)UnrealObj篇 : 反射获取Struct类型

    @Author: 白袍小道 转载请说明     案例一:蓝图传递任意Struct ,导出struct的相关属性 相关: 1.宏:DECLARE_FUNCTION: 此宏用于在自动生成的样板代码中声明t ...

  7. [转载]压力测试工具siege的用法

    压力测试工具siege 原文:http://blog.csdn.net/qingye2008/article/details/34500949 Siege是Linux下的一个web系统的压力测试工具, ...

  8. Visual Studio 2013安装包

    点击下载

  9. 深度可分卷积(Depthwise Separable Conv.)计算量分析

    上次读到深度可分卷积还是去年暑假,各种细节都有些忘了.记录一下,特别是计算量的分析过程. 1. 标准卷积和深度可分卷积 标准卷积(MobileNet论文中称为Standard Convolution, ...

  10. MongoDB复制二:复制集的管理

    1.修改oplog的大小  需要在每个机器上都配置.先在secondary上操作,最后在primary上操作. 1)以单机的方式重启复制集的实例 db.shutdownServer() 在新的端口中启 ...