【线段树】Interval GCD
题目描述
给定一个长度为N的数列A,以及M条指令 (N≤5*10^5, M<=10^5),每条指令可能是以下两种之一:
“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。
“Q l r”,表示询问 A[l],A[l+1],…,A[r] 的最大公约数(GCD)。
输入
第一行两个整数N,M,第二行N个整数Ai,接下来M行每条指令的格式如题目描述所示。
输出
对于每个询问,输出一个整数表示答案。
样例输入
5 5
1 3 5 7 9
Q 1 5
C 1 5 1
Q 1 5
C 3 3 6
Q 2 4
样例输出
1
2
4
提示
N,M≤2*10^5 l<=r,数据保证任何时刻序列中的数都是不超过2^62-1的正整数。
题解
gcd(x,y)=gcd(x,y-x),gcd(x,y,z)=gcd(x,y-x,z-y)……对任意多个整数都成立 然后用线段树维护这个差分序列,更新gcd。再用树状数组来维护原序列x的值。细节注意
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define L(u) (u<<1)
#define R(u) (u<<1|1)
const int maxn=5e5+10;
ll c[maxn];
int n,m;
template<class T>
void read(T &res) {
res = 0;
char c = getchar();
T f = 1;
while(c < '0' || c > '9')
{
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
{
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {
putchar('-');
x = -x;
}
if(x >= 10)
{
out(x / 10);
}
putchar('0' + x % 10);
}
struct Node{
int l,r;
ll val;
}node[maxn<<2];
int lowbit(int x)
{
return x&-x;
}
void add(int x,ll val)
{
for (int i=x;i<=n;i+=lowbit(i))
c[i]+=val;
}
ll get_sum(int x)
{
ll ret=0;
for (int i=x;i>=1;i-=lowbit(i))
ret+=c[i];
return ret;
}
ll s[maxn],a[maxn];
void push_up(int u){//
node[u].val=__gcd(node[L(u)].val,node[R(u)].val);
}
void build(int u,int l,int r){
node[u].l=l,node[u].r=r;
if(l==r){
node[u].val=s[l];
return;
}
int mid=(l+r)>>1;
build(L(u),l,mid);
build(R(u),mid+1,r);
push_up(u);
}
ll query(int u,int l,int r){
if(l<=node[u].l&&node[u].r<=r){
return node[u].val;
}
int mid=(node[u].l+node[u].r)>>1;
if(r<=mid) return query(L(u),l,r);
else if(l>mid) return query(R(u),l,r);
else return __gcd(query(L(u),l,mid),query(R(u),mid+1,r));
}
void update(int u,int x,ll val){
if(node[u].l==node[u].r){
node[u].val+=val;
return;
}
int mid=(node[u].l+node[u].r)>>1;
if(x<=mid) update(L(u),x,val);
else update(R(u),x,val);
push_up(u);
}
int main(){
read(n);
read(m);
for (int i = 1; i <=n ; ++i) {
read(a[i]);
s[i]=a[i]-a[i-1];
add(i,s[i]);
}
char str;int l,r;
ll d;
build(1,1,n);
for(int i=1;i<=m;++i) {
scanf(" %c", &str);
if (str == 'C') {
read(l);
read(r);
read(d);
add(l, d);
add(r + 1, -d);
update(1, l, d);
if (r + 1 <= n)update(1, r + 1, -d);
} else {
read(l);read(r);
ll ans = abs(__gcd(get_sum(l), query(1, l+1, r)));
out(ans);
puts("");
}
}
}
【线段树】Interval GCD的更多相关文章
- D - 小Z的加油店 线段树+差分+GCD
D - 小Z的加油店 HYSBZ - 5028 这个题目是一个线段树+差分+GCD 推荐一个差分的博客:https://www.cnblogs.com/cjoierljl/p/8728110.ht ...
- Codeforces 914D - Bash and a Tough Math Puzzle 线段树,区间GCD
题意: 两个操作, 单点修改 询问一段区间是否能在至多一次修改后,使得区间$GCD$等于$X$ 题解: 正确思路; 线段树维护区间$GCD$,查询$GCD$的时候记录一共访问了多少个$GCD$不被X整 ...
- 线段树 Interval Tree
一.线段树 线段树既是线段也是树,并且是一棵二叉树,每个结点是一条线段,每条线段的左右儿子线段分别是该线段的左半和右半区间,递归定义之后就是一棵线段树. 例题:给定N条线段,{[2, 5], [4, ...
- Codeforces.914D.Bash and a Tough Math Puzzle(线段树)
题目链接 \(Description\) 给定一个序列,两种操作:一是修改一个点的值:二是给一个区间\([l,r]\),问能否只修改一个数使得区间gcd为\(x\). \(Solution\) 想到能 ...
- Bash and a Tough Math Puzzle CodeForces - 914D (线段树二分)
大意:给定序列, 单点修改, 区间询问$[l,r]$内修改至多一个数后$gcd$能否为$x$ 这题比较有意思了, 要注意到询问等价于$[l,r]$内最多有1个数不为$x$的倍数 可以用线段树维护gcd ...
- 多校hdu5726 线段树+预处理
第一问是没有修改的线段树,第二问暴力预处理,因为gcd的结果不会很多 在预处理阶段需要把每个区间的gcd相等的数量储存起来(用map容器),在一个序列例如:12467,枚举左区间L直到n此处时间为O( ...
- hdu-3071 Gcd & Lcm game---质因数分解+状态压缩+线段树
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3071 题目大意: 给定一个长度为n的序列m次操作,操作的种类一共有三种 查询 L :查询一个区间的所 ...
- CS Academy Gcd on a Circle(dp + 线段树)
题意 给你一个长为 \(n\) 的环,你可以把它断成任意 \(k\) 段 \((1 < k \le n)\) ,使得每一段的 \(\gcd\) 都 \(>1\) . 问总共有多少种方案,对 ...
- Codeforces 311D Interval Cubing 数学 + 线段树 (看题解)
Interval Cubing 这种数学题谁顶得住啊. 因为 (3 ^ 48) % (mod - 1)为 1 , 所以48个一个循环节, 用线段树直接维护. #include<bits/stdc ...
随机推荐
- Spring学习(三)——@PropertySource,@ImportResource,@Bean注解
@PropertySource注解是将配置文件中 的值赋值给POJO 项目结构如下 一.创建一个Person.Java文件: import org.springframework.boot.conte ...
- [极客大挑战 2019]FinalSQL
0x00 知识点 盲注 0x01 解题 根据题目提示盲注,随便点几下找到注入点 发现我们输入^符号成功跳转页面,证明存在注入 1^(ord(substr((select(group_concat(sc ...
- 2020/1/30 PHP代码审计之文件上传漏洞
0x00 漏洞简介 文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力.这种攻击是最为直接和有效的,"文件上传"本身是没有问题,有问题的是 ...
- C语言备忘录——向上取整
众所周知,C语言的取整方式是向下取整,昨天老师留了一道思考题,问我们C语言怎么向上取整,当时我第一反应就是ceil(),老师说不能用if……else之类的,函数也不行.当时想了想没事不用就不用,去ma ...
- pytorch 数据操作
数据操作 在深度学习中,我们通常会频繁地对数据进行操作.作为动手学深度学习的基础,本节将介绍如何对内存中的数据进行操作. 在PyTorch中,torch.Tensor是存储和变换数据的主要工具.如果你 ...
- 微信小程序下载图片到本地
downloadImg: function(e){ //触发函数 console.log(e.currentTarget.dataset.url) wx.downloadFile({ url: e.c ...
- (递归)P1036 选数
#include<stdio.h>#include<math.h>int x[20],n,k,i; //判断是否质数 int isprime(int n){ for(i= ...
- Hough直线and圆环变换(如何检测直线、圆环)
1.霍夫变换 2.cv2.HoughLines() 返回值就是(ρ, θ).ρ 的单位是像素,θ 的单位是弧度.这个函数的第一个参 数是一个二值化图像,所以在进行霍夫变换之前要首先进行二值化,或者进行 ...
- Maven--部署构件至 Nexus
日常开发生成的快照版本构件可以直接部署到 Nexus 中策略为 Snapshot 的宿主仓库中,项目正式发布的构件则应该部署到 Nexus 中策略为 Release 的宿主仓库中. <proje ...
- PowerDesigner 表格导出为excel(转载)
选中tablesctrl + shift +x 然后运行脚本 '******************************************************************** ...