【bzoj5028】小Z的加油店 扩展裴蜀定理+差分+线段树
题目描述
输入
输出
样例输入
3 4
2 3 4
1 1 3
2 2 2 1
1 1 3
1 2 3
样例输出
1
2
4
题解
扩展裴蜀定理+差分+线段树
由 【bzoj2257】瓶子和燃料 的结论,答案为区间 $\gcd$ 。
那么问题转化为:区间加、区间求 $\gcd$ 。
直接解决这个问题比较困难。我们知道,$\gcd(a,b,c)=\gcd(a,b-a,c-b)$ ,即区间 $\gcd$ 等于 $l$ 位置的数与 $[l+1,r]$ 的差分数组的 $\gcd$ 。而区间加在差分数组上表现为单点加减,较容易维护。
因此对原数组求差分数组,修改时在差分数组上进行单点加减,查询时查询差分数组的前缀和及区间 $\gcd$ ,最大公约数即为答案。
时间复杂度 $O(n\log n)$ (求 $\gcd$ 的 $\log$ 在线段树pushup的过程中均摊掉了,因此只有一个 $\log$ )
- #include <cstdio>
- #include <algorithm>
- #define N 100010
- #define lson l , mid , x << 1
- #define rson mid + 1 , r , x << 1 | 1
- using namespace std;
- int a[N] , sum[N << 2] , val[N << 2];
- inline int gcd(int a , int b)
- {
- int t;
- while(b) t = a , a = b , b = t % b;
- return a;
- }
- inline void pushup(int x)
- {
- sum[x] = sum[x << 1] + sum[x << 1 | 1] , val[x] = gcd(val[x << 1] , val[x << 1 | 1]);
- }
- void build(int l , int r , int x)
- {
- if(l == r)
- {
- sum[x] = val[x] = a[l] - a[l - 1];
- return;
- }
- int mid = (l + r) >> 1;
- build(lson) , build(rson);
- pushup(x);
- }
- void update(int p , int a , int l , int r , int x)
- {
- if(p > r) return;
- if(l == r)
- {
- sum[x] += a , val[x] += a;
- return;
- }
- int mid = (l + r) >> 1;
- if(p <= mid) update(p , a , lson);
- else update(p , a , rson);
- pushup(x);
- }
- int qsum(int p , int l , int r , int x)
- {
- if(l == r) return sum[x];
- int mid = (l + r) >> 1;
- if(p <= mid) return qsum(p , lson);
- else return qsum(p , rson) + sum[x << 1];
- }
- int qval(int b , int e , int l , int r , int x)
- {
- if(b > e) return 0;
- if(b <= l && r <= e) return val[x];
- int mid = (l + r) >> 1 , ans = 0;
- if(b <= mid) ans = gcd(ans , qval(b , e , lson));
- if(e > mid) ans = gcd(ans , qval(b , e , rson));
- return ans;
- }
- int main()
- {
- int n , m , i , opt, l , r , x;
- scanf("%d%d" , &n , &m);
- for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]);
- build(1 , n , 1);
- while(m -- )
- {
- scanf("%d%d%d" , &opt , &l , &r);
- if(opt == 1) printf("%d\n" , abs(gcd(qsum(l , 1 , n , 1) , qval(l + 1 , r , 1 , n , 1))));
- else scanf("%d" , &x) , update(l , x , 1 , n , 1) , update(r + 1 , -x , 1 , n , 1);
- }
- return 0;
- }
【bzoj5028】小Z的加油店 扩展裴蜀定理+差分+线段树的更多相关文章
- [BZOJ5028]小Z的加油店
[BZOJ5028]小Z的加油店 题目大意: 一个长度为\(n(n\le10^5)\)的数列,\(m(m\le10^5)\)次操作,支持区间加和区间\(\gcd\). 思路: 线段树维护差分,\(\g ...
- bzoj5028小Z的加油店(线段树+差分)
题意:维护支持以下两种操作的序列:1 l r询问a[l...r]的gcd,2 l r x把a[l...r]全部+x 题解:一道经典题.根据gcd(a,b)=gcd(a-b,b)以及区间加可知,这题可以 ...
- D - 小Z的加油店 线段树+差分+GCD
D - 小Z的加油店 HYSBZ - 5028 这个题目是一个线段树+差分+GCD 推荐一个差分的博客:https://www.cnblogs.com/cjoierljl/p/8728110.ht ...
- 【bzoj2257】[Jsoi2009]瓶子和燃料 扩展裴蜀定理+STL-map
题目描述 给出 $n$ 个瓶子和无限的水,每个瓶子有一定的容量.每次你可以将一个瓶子装满水,或将A瓶子内的水倒入B瓶子中直到A倒空或B倒满.从中选出 $k$ 个瓶子,使得能够通过这 $k$ 个瓶子凑出 ...
- 【bzoj1441】Min 扩展裴蜀定理
题目描述 给出n个数(A1...An)现求一组整数序列(X1...Xn)使得S=A1*X1+...An*Xn>0,且S的值最小 输入 第一行给出数字N,代表有N个数 下面一行给出N个数 输出 S ...
- BZOJ 5028 小Z的加油店
[题解] 本题要求求出区间内的各个元素通过加减之后能够得出的最小的数,那么根据裴蜀定理可知答案就是区间内各个元素的最大公约数. 那么本题题意化简成了维护一个序列,支持区间加上某个数以及查询区间元素的最 ...
- bzoj 5028: 小Z的加油店——带修改的区间gcd
Description 小Z经营一家加油店.小Z加油的方式非常奇怪.他有一排瓶子,每个瓶子有一个容量vi.每次别人来加油,他会让 别人选连续一段的瓶子.他可以用这些瓶子装汽油,但他只有三种操作: 1. ...
- 5028: 小Z的加油店(线段树)
NOI2012魔幻棋盘弱化版 gcd(a,b,c,d,e)=gcd(a,b-a,c-b,d-c,e-d) 然后就可以把区间修改变成差分后的点修了. 用BIT维护原序列,线段树维护区间gcd,支持点修区 ...
- 【BZOJ】5028: 小Z的加油店
[算法]数学+线段树/树状数组 [题解] 首先三个操作可以理解为更相减损术或者辗转相除法(待证明),所以就是求区间gcd. 这题的问题在线段树维护gcd只能支持修改成一个数,不支持加一个数. 套路:g ...
随机推荐
- Python中的对象引用、浅拷贝与深拷贝
最近项目中遇到一个Python浅拷贝机制引起的bug,由于对于Python中对象引用.赋值.浅拷贝/深拷贝机制没有足够的认识,导致调试了很久才发现问题,这里简单记录一下相关概念. 在Python的设计 ...
- ADO.NET操作MySQL数据库
前言 ADO.NET包括5大对象,分别是Connection.Command.DataReader.DataSet.DataAdapter,使用ADO.NET访问数据库有两个步骤:建立数据库连接.读取 ...
- protobuf工程的编译以及使用
一. 获取Protocol Buffer 1.1 获得源码 Github:ProtocolBuffer源码 Git clone之:git clone https://github.com/google ...
- 第七篇 Postman+Node.js+Newman+Jenkins实现自动化测试
今天终于不咋忙了,学习整理一下一直想做却没实现的事儿,这事已经折磨团队半年之久了.因为项目是B端业务的测试,测试过程中需要生产大量的测试数据,而且都是跨多个系统的测试,对于后置流程的测试,这些同学往往 ...
- vue cli 3 +jquery
const webpack = require('webpack')module.exports = { // baseUrl type:{string} default:'/' // 将部署应用程序 ...
- 前端之JavaScript(二)
一.概述 本篇主要介绍JavaScript的BOM和DOM操作,在前端之JavaScript(一)中介绍了JavaScript基础知识 1.1.BOM和DOM BOM(Browser Object M ...
- VS默认的类前缀(访问控制符)是internal
VS默认的类前缀(访问控制符)是internal 大家都知道VS默认新建的class的时候,class前面是什么都没有的,按照规则,这个class的可见性是internal,但是说实话,很多人包括我在 ...
- python sys.argv是什么?
1.sys.argv 是获取运行python文件的时候命令行参数,且以list形式存储参数 2.sys.argv[0] 代表当前module的名字 下面的代码文件是a.py,当我不用IDE工具,只用命 ...
- Paper Reading - Show and Tell: A Neural Image Caption Generator ( CVPR 2015 )
Link of the Paper: https://arxiv.org/abs/1411.4555 Main Points: A generative model ( NIC, GoogLeNet ...
- Python 招聘信息爬取及可视化
自学python的大四狗发现校招招python的屈指可数,全是C++.Java.PHP,但看了下社招岗位还是有的.于是为了更加确定有多少可能找到工作,就用python写了个爬虫爬取招聘信息,数据处理, ...