【算法】数学+线段树/树状数组

【题解】

首先三个操作可以理解为更相减损术或者辗转相除法(待证明),所以就是求区间gcd。

这题的问题在线段树维护gcd只能支持修改成一个数,不支持加一个数。

套路:gcd(a,b,c,d,e)=gcd(a-b,b-c,c-d,d-e,e),也就是所有数的gcd可以转化为所有差值和最后一个数的gcd

那么只需要查询区间差值gcd和一个数。

对于区间差值gcd查询,区间加数只会导致两个单位的差值变化,所以可以用线段树单点修改区间查询gcd。

对于一个数查询,就用树状数组维护区间加值和单点查询就行了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=;
struct tree{int l,r,g;}t[maxn*];
int a[maxn],c[maxn],n,m; int read()
{
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
void modify(int x,int k){for(int i=x;i<=n;i+=lowbit(i))c[i]+=k;}
int query(int x){int as=;for(int i=x;i>=;i-=lowbit(i))as+=c[i];return as;}//as给初值
void build(int k,int l,int r){
t[k].l=l;t[k].r=r;
if(l==r)t[k].g=a[l]-a[l+];
else{
int mid=(l+r)>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
t[k].g=gcd(t[k<<].g,t[k<<|].g);
}
}
void add(int k,int x,int v){
if(t[k].l==t[k].r)t[k].g+=v;
else{
int mid=(t[k].l+t[k].r)>>;
if(x<=mid)add(k<<,x,v);
else add(k<<|,x,v);
t[k].g=gcd(t[k<<].g,t[k<<|].g);
}
}
int ask(int k,int l,int r){
if(l<=t[k].l&&t[k].r<=r)return t[k].g;
else{
int mid=(t[k].l+t[k].r)>>,x1=,x2=;
if(l<=mid)x1=ask(k<<,l,r);
if(r>mid)x2=ask(k<<|,l,r);
if(x1&&x2)return gcd(x1,x2);
if(x1)return x1;
return x2;
}
}
int ab(int x){return x>?x:-x;}
int main(){
n=read();m=read();
a[]=;
for(int i=;i<=n;i++)a[i]=read(),modify(i,a[i]-a[i-]);
a[n+]=;
build(,,n);
for(int i=;i<=m;i++){
int p=read(),l=read(),r=read();
if(l>r)swap(l,r);
if(p==){
if(l==r)printf("%d\n",query(r));
else printf("%d\n",ab(gcd(ask(,l,r-),query(r))));//gcd不怕0
}
else{
int v=read();
if(l>)add(,l-,-v);//注意边界!
add(,r,v);
modify(l,v);
if(r<n)modify(r+,-v);
}
}
return ;
}

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

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

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

  2. BZOJ 5028 小Z的加油店

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

  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. CC3200模块的内存地址划分和bootloader(一)

    1. CC3200的内存地址划分非常特殊,如果没测试的话,很容易懵逼.我们先看芯片手册里面的内存地址.芯片的RAM是256KB,下图的0x2000 0000-0x2003 FFFF,正好是256KB. ...

  2. html简单的分享功能

    超级简单的分享. 包括:QQ.QQ空间.新浪微博.腾讯微博,微信(只是一个二维码): 1.首先是html代码: (前端我并不太会,一直用的都是bootstrap) <div class=&quo ...

  3. Django笔记 —— 模型高级进阶

    最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...

  4. Java笔试题-线程编程方面

      Ja 线程编程方面 60.java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 答:有两种实现方法,分别是继承Thread类与实现R ...

  5. adb常用命令(手机测试)

                                                   ADB安装与常用命令详解 一.ADB意义 adb的全称为Android Debug Bridge,就是起到 ...

  6. ProxySQL初体验

      Preface       As we all know,it's a common sense that separate reading and writing operations can ...

  7. TortoiseSVN的安装使用

    下面分享一篇关于TortoiseSVN的安装以及使用 1.运行TortoiseSVN-1.6.6.17493-win32-svn-1.6.6.msi程序, 开始安装 2.点击Next, 下一步 3.选 ...

  8. fiddler抓包-简单易操作(二)

    Fiddler抓包简介 原理:fiddler是通过改写HTTP代理,客户端和服务器进行交互时,数据会从他那里通过,来监控和截取数据.我是这样理解的,如果不对,欢迎指正.如下图: 如果想要抓到数据包,首 ...

  9. 解决Unbuntu终端菱形乱码问题

    原因:安装时为了学习方便选择中文安装,其字符编码相关配置如下(在/etc/default/locale中) LANG="Zh_CN.UTF-8 "LANGUAGE="zh ...

  10. Beat 冲刺 (3/7)

    队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 1.界面的修改与完善 展示GitHub当日代码/文档签入记 ...