【题解】

  本题要求求出区间内的各个元素通过加减之后能够得出的最小的数,那么根据裴蜀定理可知答案就是区间内各个元素的最大公约数。

  那么本题题意化简成了维护一个序列,支持区间加上某个数以及查询区间元素的最大公约数。

  我们要证明这样一个定理:

    对于一个序列(a,b,c,d,...),gcd(a,b,c,d,...)=gcd(a,b-a,c-b,d-c,...),文字表述就是原序列的最大公约数等于序列差分后的最大公约数。

  证明方法如下:

      1,设t为序列(a,b,c,d,...)的公约数,a<b<c,b=k1*a+x1,c=k2*a+x2,

    那么我们有t|a,t|b,t|c

    所以有t|x1,t|x2

    所以t|(x2-x1)

    所以t|(k1-1)*a+x1,t|(k2-k1)*a+(x2-x1)

    即t也是序列(a,b-a,c-b,...)的公约数

    同理,(a,b,c,...)的任一公约数也是(a,b-a,c-b,...)的公约数。

      2,设t为序列(a,b-a,c-b,...)的公约数,

    那么有t|a, t|(k1-1)*a+x1, t|(k2-k1)*a+(x2-x1)

    所以有t|x1,t|x2-x1

    所以t|x2

    所以t|a, t|k1*a+x1,t|k2*a+x2

    即t也是序列(a,b,c,...)的公约数

    同理,(a,b-a,c-b,...)的任一公约数也是(a,b,c,...)的公约数。

   综上,gcd(a,b,c,...)=gcd(a,b-a,c-b,...).

  证明完这个定理之后,我们就可以把题意化为求区间第一个元素与后面元素的差分值的GCD

  我们先把原序列差分,线段树维护差分数组的GCD。因为我们已经进行了差分,所以区间加操作变成了点修改,可以直接在线段树上logn完成。

 #include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
#define rg register
#define N 100010
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((a[u].l+a[u].r)>>1)
using namespace std;
int n,m,v[N],c[N],t[N];
struct tree{
int l,r,g;
}a[N<<];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
int gcd(int x,int y){return y?gcd(y,x%y):x;}
void build(int u,int l,int r){
a[u].l=l; a[u].r=r;
if(l<r) build(ls,l,mid),build(rs,mid+,r),a[u].g=gcd(a[ls].g,a[rs].g);
else a[u].g=abs(c[l]);
}
void update(int u,int pos,int data){
if(a[u].l==a[u].r){
a[u].g=data; return;
}
update(pos<=mid?ls:rs,pos,data);
a[u].g=gcd(a[ls].g,a[rs].g);
}
int query(int u,int l,int r){
if(l<=a[u].l&&a[u].r<=r) return a[u].g;
int ret=; bool goleft=;
if(l<=mid) ret=query(ls,l,r),goleft=;
if(r>mid){
if(goleft) ret=gcd(ret,query(rs,l,r));
else ret=query(rs,l,r);
}
return ret;
}
inline void add(int x,int y){for(;x<=n+;x+=(x&-x)) t[x]+=y;}
inline int qsum(int x){int ret=; for(;x;x-=(x&-x)) ret+=t[x]; return ret;}
int main(){
n=read(); m=read();
for(rg int i=;i<=n;i++) v[i]=read(),c[i]=v[i]-v[i-],add(i,c[i]);
build(,,n);
while(m--){
int opt=read(),l=read(),r=read(); if(l>r) swap(l,r);
if(opt==){
if(l<r) printf("%d\n",gcd(qsum(l),query(,l+,r)));
else printf("%d\n",qsum(l));
}
else{
int del=read();
c[l]+=del; c[r+]-=del;
add(l,del); if(r<n) add(r+,-del);
update(,l,abs(c[l])); if(r<n) update(,r+,abs(c[r+]));
}
}
return ;
}

    

BZOJ 5028 小Z的加油店的更多相关文章

  1. bzoj 5028: 小Z的加油店——带修改的区间gcd

    Description 小Z经营一家加油店.小Z加油的方式非常奇怪.他有一排瓶子,每个瓶子有一个容量vi.每次别人来加油,他会让 别人选连续一段的瓶子.他可以用这些瓶子装汽油,但他只有三种操作: 1. ...

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

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

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

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

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

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

  5. [BZOJ5028]小Z的加油店

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

  6. BZOJ 5028 小z的加油站

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

  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. python-----列表生成式和列表生成器表达

    列表表达式: 程序一: 常规写法: L = [] for x in range(1, 11): L.append(x * x) print(L) #[1, 4, 9, 16, 25, 36, 49, ...

  2. springboot开发过程中的小坑(持续更新)

    1. 启动的Application必须放到一个package下面,如下: package com.example.kikidemo; import org.springframework.boot.S ...

  3. /bin/bash: jar: command not found(转载)

    转自:http://blog.csdn.net/zhangdaiscott/article/details/23138023 /bin/bash: jar: command not found 解决办 ...

  4. bzoj 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚【dp+线段树】

    设f[i]为i时刻最小花费 把牛按l升序排列,每头牛能用f[l[i]-1]+c[i]更新(l[i],r[i])的区间min,所以用线段树维护f,用排完序的每头牛来更新,最后查询E点即可 #includ ...

  5. [C陷阱和缺陷] 第7章 可移植性缺陷

      C语言在许多不同的系统平台上都有实现.的确,使用C语言编写程序的一个首要原因就是,C程序能够方便地在不同的编程环境中移植.   不同的系统有不同的需求,因此我们应该能够预料到,机器不同则其上的C语 ...

  6. 构造 Codeforces Round #Pi (Div. 2) B. Berland National Library

    题目传送门 /* 题意:给出一系列读者出行的记录,+表示一个读者进入,-表示一个读者离开,可能之前已经有读者在图书馆 构造:now记录当前图书馆人数,sz记录最小的容量,in数组标记进去的读者,分情况 ...

  7. Java compiler level does not match the version of the installed Java project facet问题处理

    从SVN上下载应用后在Problems面板中提示以下错误信息: Java compiler level does not match the version of the installed Java ...

  8. dos 下小tip

    tip 1:日期的格式化 方法如下: Echo %Date:~0,4%%Date:~5,2%%Date:~8,2%或者Set dt=%Date:~0,4%%Date:~5,2%%Date:~8,2%E ...

  9. MySql学习笔记(1)-安装

    一.安装环境 操作系统:win7 64ibt MySql版本:5.7.10.0 二.安装过程 1.点击Add 2.选择需要安装的组件 3.Excute 4.Next 5.Next 6.进入服务器配置 ...

  10. php函数的定义和声明

    1.函数的定义 函数是一个被命名的独立的代码段,它执行特定任务,并可以给调用它的程序返回值. 2.函数的优点 提高程序的重用性 提高程序的可维护性 可以提高软件的开发效率 提高软件的可靠性 控制程序的 ...