区间加值,区间gcd, 牛客949H
牛客小白月赛16H 小阳的贝壳
题意
维护一个数组,支持以下操作:
1: 区间加值
2: 询问区间相邻数差的绝对值的最大值
3: 询问区间gcd
题解
设原数组为\(a\), 用线段树维护\(b[i] = a[i] - a[i - 1]\),
线段树维护三个值:min, max, gcd
对于操作1:
L 位置加上x, R + 1位置减去x
对于操作2:
查询区间(L + 1, R) 的 min, max, 取绝对值大者
对于操作3:
考虑gcd的性质
\(gcd(a, b, c, d, ...) = gcd(a, b - a, c - b, d - c, ...)\)
查询区间(L + 1, R) 的 gcd, 就是\(gcd(b - a, c - b, d - c, ...)\)
然后用另一个东西维护原来的a数列
可以用另一颗线段树lazy标记维护
我用的是树状数组差分,将区间更新和单点查询转化为单点更新和前缀和查询
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int mx[N << 2], mn[N << 2], g[N << 2], c[N], a[N], b[N];
int n, m, op, l, r, x;
void add(int pos, int val) {
for(; pos <= n; pos += pos & -pos)
c[pos] += val;
}
int ask(int pos) {
int ans = 0;
for(; pos; pos -= pos & -pos)
ans += c[pos];
return ans;
}
void pushup(int rt) {
mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
mn[rt] = min(mn[rt << 1], mn[rt << 1 | 1]);
g[rt] = __gcd(g[rt << 1], g[rt << 1 | 1]);
}
void build(int rt, int l, int r) {
if(l == r) {
mx[rt] = mn[rt] = g[rt] = b[l];
return;
}
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
pushup(rt);
}
void update(int rt, int l, int r, int pos, int val) {
if(l == r) {
mx[rt] += val;
mn[rt] += val;
g[rt] += val;
return;
}
int mid = l + r >> 1;
if(pos <= mid)
update(rt << 1, l, mid, pos, val);
else
update(rt << 1 | 1, mid + 1, r, pos, val);
pushup(rt);
}
int querymax(int rt, int l, int r, int L, int R) {
if(L <= l && r <= R) {
return max(abs(mn[rt]), abs(mx[rt]));
}
int mid = l + r >> 1, ans = 0;
if(L <= mid)
ans = max(ans, querymax(rt << 1, l, mid, L, R));
if(R > mid)
ans = max(ans, querymax(rt << 1 | 1, mid + 1, r, L, R));
return ans;
}
int querygcd(int rt, int l, int r, int L, int R) {
if(L <= l && r <= R) {
return g[rt];
}
int mid = l + r >> 1, ans = 0;
if(L <= mid)
ans = __gcd(ans, querygcd(rt << 1, l, mid, L, R));
if(R > mid)
ans = __gcd(ans, querygcd(rt << 1 | 1, mid + 1, r, L, R));
return abs(ans);
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
add(i, a[i] - a[i - 1]);
b[i] = a[i] - a[i - 1];
}
build(1, 1, n);
while(m--) {
scanf("%d%d%d", &op, &l, &r);
if(op == 1) {
scanf("%d", &x);
add(l, x);
update(1, 1, n, l, x);
if(r != n) {
add(r + 1, -x);
update(1, 1, n, r + 1, -x);
}
}
else if(op == 2) {
if(l == r)
puts("0");
else
printf("%d\n", querymax(1, 1, n, l + 1, r));
}
else {
int a = ask(l), b;
if(l == r)
b = 0;
else
b = querygcd(1, 1, n, l + 1, r);
printf("%d\n", __gcd(a, b));
}
}
return 0;
}
区间加值,区间gcd, 牛客949H的更多相关文章
- 二叉树中和为某一值的路径 牛客网 程序员面试金典 C++ Python
二叉树中和为某一值的路径 牛客网 程序员面试金典 题目描述 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一 ...
- HDU 3577 Fast Arrangement ( 线段树 成段更新 区间最值 区间最大覆盖次数 )
线段树成段更新+区间最值. 注意某人的乘车区间是[a, b-1],因为他在b站就下车了. #include <cstdio> #include <cstring> #inclu ...
- cf834D(dp+线段树区间最值,区间更新)
题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...
- HihoCoder1333 :平衡树(splay+lazy)(区间加值,区间删除)
描述 小Ho:好麻烦啊~~~~~ 小Hi:小Ho你在干嘛呢? 小Ho:我在干活啊!前几天老师让我帮忙管理一下团队的人员,但是感觉好难啊. 小Hi:说来听听? 小Ho:事情是这样的.我们有一个运动同好会 ...
- POJ 3468 A Simple Problem with Integers(线段树功能:区间加减区间求和)
题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS Memory Limit ...
- 线段树 区间加 gcd 差分 小阳的贝壳
小阳的贝壳 如果线段树要维护区间gcd 这个很简单,但是如果有了区间加,维护gcd 就比较麻烦了. 这个首先可以证明的是 gcd(x,y,z)=gcd(x,y-x,z-y) 这个可以推到 n 个 ...
- HDU 5828 Rikka with Sequence(线段树区间加开根求和)
Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he g ...
- 【BZOJ】1798: [Ahoi2009]Seq 维护序列seq 线段树多标记(区间加+区间乘)
[题意]给定序列,支持区间加和区间乘,查询区间和取模.n<=10^5. [算法]线段树 [题解]线段树多重标记要考虑标记与标记之间的相互影响. 对于sum*b+a,+c直接加上即可. *c后就是 ...
- 线段树_区间加乘(洛谷P3373模板)
题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字 ...
随机推荐
- pyQT Dialog默认选中某一个选项问题的解决
方法一: 在新建ui文件时不要新建Dialog # -*- coding: utf-8 -*- # Form implementation generated from reading ui file ...
- 33 N皇后问题
原题网址:https://www.lintcode.com/zh-cn/old/problem/n-queens/# n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击. 给定一个整 ...
- Struts2转换器
为什么进行类型转换 在基于HTTP协议的Web应用中 客户端请求的所有内容都以文本编码方式传输到服务器端 服务器端的编程语言却有着丰富的数据类型 继承StrutsTypeConverter抽象类 继承 ...
- 在Jsp中调用静态资源,路径配置问题
在Jsp中调用图片.JS脚本等,针对取得的路径有两种调用方式: 1.放入Body中生成绝对路径(不建议) <%@ page language="java" import=&q ...
- Leetcode322. Coin Change零钱兑换
给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总金额,返回 -1. 示例 1: 输入: coins = ...
- 【心无旁骛】vue-ts-daily
这是一个非常有意思的项目,我们先来看看效果 这个项目所用的技术也比较有意思,它的技术栈为vue2.5 + Typescript + vuex + vue-router 放下博主的项目地址吧,https ...
- 最全的CSS hack没有之一
1.何为HACK? 简单的说,HACK就是只有特定浏览器才能识别这段hack代码.Hack也可以说是让前端最为头疼的问题,因为要写N多种兼容代码.当然,IE是最让人蛋疼的. 一般来说,CSS HACK ...
- C# 窗体内容显示不全
在T430上安装skyline的CS版时候,发现登陆窗口显示的内容不全,第二个缓冲的窗口也显示不全.设置了下面的参数后就可以了.
- PAT甲级——A1025 PAT Ranking
Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhe ...
- Java学习笔记 - 类方法与代码块的执行顺序
类的初始化顺序 使用一个简单的父子类例子来做示范,代码执行顺序在代码后有标注. class Parent { public static String p_StaticField = "父类 ...