题目链接:点击查看

题目大意:给出一个长度为 nnn 的序列,需要执行 mmm 次操作,每次操作分为下列两种类型:

  1. C l r d:将区间 [l,r][l,r][l,r] 位置的数字都加上 ddd
  2. Q l r:询问区间 [l,r][l,r][l,r] 的最大公约数

题目分析:首先是推广一下最大公约数的公式:

  • gcd(a,b)=gcd(a,b−a)gcd(a,b)=gcd(a,b−a)gcd(a,b)=gcd(a,b−a)
  • gcd(a,b,c)=gcd(a,b−a,c−b)gcd(a,b,c)=gcd(a,b-a,c-b)gcd(a,b,c)=gcd(a,b−a,c−b)
  • gcd(a1,a2,...an)=gcd(a1,a2−a1,...,an−an−1)gcd(a_1,a_2,...a_n)=gcd(a_1,a_2-a_1,...,a_n-a_{n-1})gcd(a1​,a2​,...an​)=gcd(a1​,a2​−a1​,...,an​−an−1​)

如此一来我们可以同时维护一下原数组以及差分数组,设 bi=ai−ai−1b_i=a_i-a_{i-1}bi​=ai​−ai−1​,对于每次修改而言,差分数组是单点修改,而原数组是区间修改。对于每次查询而言,差分数组是区间查询,原数组是单点查询。

最后说一下改如何查询,对于 [l,r][l,r][l,r] 的查询,我们只需要输出 gcd(a[l],b[l+1],...,b[r])gcd(a[l],b[l+1],...,b[r])gcd(a[l],b[l+1],...,b[r]) 就是答案了

代码:

// Problem: 区间最大公约数
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/247/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f;
}
template<typename T>
inline void write(T x)
{if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
LL c[N],a[N];
int n,m;
struct Node {int l,r;LL sum;
}tree[N<<2];
void pushup(int k) {tree[k].sum=__gcd(tree[k<<1].sum,tree[k<<1|1].sum);
}
void build(int k,int l,int r) {tree[k]={l,r};if(l==r) {tree[k].sum=a[l]-a[l-1];return;}int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);pushup(k);
}
void update(int k,int pos,LL val) {if(pos>n) {return;}if(tree[k].l==tree[k].r) {tree[k].sum+=val;return;}int mid=(tree[k].l+tree[k].r)>>1;if(pos<=mid) {update(k<<1,pos,val);} else {update(k<<1|1,pos,val);}pushup(k);
}
LL query(int k,int l,int r) {if(tree[k].l>r||tree[k].r<l) {return 0;}if(tree[k].l>=l&&tree[k].r<=r) {return tree[k].sum;}return __gcd(query(k<<1,l,r),query(k<<1|1,l,r));
}
void add(LL x,LL val) {for(int i=x;i<N;i+=lowbit(i)) {c[i]+=val;}
}
LL ask(LL x) {LL ans=0;for(int i=x;i>0;i-=lowbit(i)) {ans+=c[i];}return ans;
}
int main()
{#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);read(n),read(m);for(int i=1;i<=n;i++) {read(a[i]);}build(1,1,n);while(m--) {char op[5];scanf("%s",op);if(op[0]=='Q') {int l,r;read(l),read(r);printf("%lld\n",__gcd(a[l]+ask(l),abs(query(1,l+1,r))));} else if(op[0]=='C') {int l,r;LL val;read(l),read(r),read(val);add(l,val),add(r+1,-val);update(1,l,val),update(1,r+1,-val);}}return 0;
}

AcWing - 246. 区间最大公约数(树状数组+线段树)相关推荐

  1. D-query SPOJ - DQUERY(求区间不同数的个数)(树状数组||线段树+离散)(主席树+在线)

    English Vietnamese Given a sequence of n numbers a1, a2, -, an and a number of d-queries. A d-query ...

  2. 51nod 1680区间求和 (dp+树状数组/线段树)

    不妨考虑已知一个区间[l,r]的k=1.k=2....k=r-l+1这些数的答案ans(只是这一个区间,不包含子区间) 那么如果加入一个新的数字a[i](i = r+1) 则新区间[l, i]的答案为 ...

  3. HDU 1556 前缀和 树状数组 线段树

    解法一: a[i]表示以 i作为起点,对 i-n的气球全部上色的次数  对(start,end)区间上色 ++a[start] --a[end+1]抵消掉 end+1-n的部分 问题转换为求 a的前缀 ...

  4. jzoj3854-分组【树状数组,线段树】

    正题 题目链接:https://jzoj.net/senior/#contest/show/2990/2 题目大意 一个小队满足要求 队长的地位最高 所有队员和队长的年龄差不超过kkk 给出nnn个人 ...

  5. POJ2182 HDU2711 Lost Cows【树状数组+线段树】

    Lost Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17113 Accepted: 10664 Descripti ...

  6. P2357 守墓人(树状数组/线段树)

    题目描述 在一个荒凉的墓地上 有一个令人尊敬的守墓人, 他看守的墓地从来 没有被盗过, 所以人们很放心的把自己的先人的墓 安顿在他那 守墓人能看好这片墓地是必然而不是偶然..... 因为....守墓人 ...

  7. 差分+树状数组 线段树【P2357】 守墓人

    题目描述-->p2357 守墓人 敲了一遍线段树,水过. 树状数组分析 主要思路: 差分 简单介绍一下差分(详细概念太麻烦,看下面. 给定一个数组 7 8 6 5 1 8 18 20 35 // ...

  8. NKOJ 2182 (HEOI 2012) 采花(树状数组/线段树)

    P2182[河北OI 2012 DAY1]采花 问题描述 萧芸斓是Z 国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳 了n 朵花,花有c ...

  9. 甜甜圈(树状数组)(线段树)

    文章目录 1. 树状数组维护 2.线段树维护 题目描述 艾洛喜欢吃甜食,他有n个甜甜圈,现在叠成了两叠(如下图所示),第一叠有 n1n1n1个,第二叠有 n2n2n2个 (n1+n2=n)(n1+n2 ...

  10. 模板三连击:树状数组+线段树+主席树

    没事儿干,复习模板...... 1.树状数组 本来不想写这个的,但是反正就几分钟就打完了,所以就写了,水AC数. 洛谷 P3374 [模板]树状数组 1 1 #include<cstdio> ...

最新文章

  1. python fabric使用
  2. jQuery 图片剪裁插件初探之 Jcrop
  3. python如何移动文件却不覆盖现有文件_解决python不能覆盖文件内容的方法
  4. mysql 的文件介绍_mysql 数据文件介绍
  5. 苏州银行签约神策数据,致力打造科技引领的新时代普惠银行
  6. Ubuntu 14.04 更换为阿里云源
  7. 1_1 FactoryMode 工厂模式
  8. 软件设计原则:内聚、耦合有哪几种类型?内聚度、耦合度如何比较?
  9. 作者:郑纬民,男,清华大学教授、博士生导师,中国计算机学会理事长。
  10. Codeforces Round #280 (Div. 2)
  11. reportlab 应用 打印考生成绩
  12. wavecn 2.0.0.5 正式版_iOS12.1.4正式版更新了什么 苹果iOS12.1.4新特性与升降级全攻略...
  13. 创建win10介质进度为0_MediaCreationTool(Win10介质创建工具) V10.0 官方版
  14. Nginx——Nginx实现服务端集群搭建
  15. php用户登录界面代码有背景,HTML和CSS实现动态背景登录页面
  16. android自动适应横屏,Android屏幕适配(一)--自定义View屏幕适配
  17. 小程序和服务器之间的通信,微信小程序建立服务器通信的方法
  18. JAVA毕业设计公交线路查询系统计算机源码+lw文档+系统+调试部署+数据库
  19. 记一次磁盘挂载导致mysql服务启动失败的问题
  20. 如何寄送一本武功秘籍

热门文章

  1. pytorch | Softmax->Log->NLLLoss->CrossEntropyLoss
  2. Spring Cloud Alibaba Nacos Confifig是什么
  3. MySQL select后面的子查询使用
  4. Nginx的index指令
  5. 带你从源码了解SpringBoot启动流程
  6. Protobuf序列化的原理-protobuf的基本应用
  7. ArrayBlockingQueue原理分析-dequeue方法
  8. HandlerAdapters
  9. Redis 到底有多快?
  10. springboot集成rocketmq生产者