题目大意:给定一个长度为 N 的序列,M 个操作,支持区间加,区间查询最大公约数。

题解:

先来看一个子问题,若是单点修改,区间最大公约数,则可以发现,每次修改最多改变 \(O(logn)\) 个答案,且 gcd 可以合并,因此可以直接在线段树上维护。

但是对于区间加来说,无法在已知区间加了某一个数时快速计算出新的区间最大公约数,因此,最坏情况下复杂度可能退化到 \(O(n)\)。考虑辗转相除法的性质,$$gcd(x,y,z)=gcd(x,y-x,z-y)$$可以发现,若维护的是原序列的差分序列,则问题会转化成上述子问题。且原问题询问的答案为$$gcd(a[l],query(l+1,r))$$,即可保证复杂度不退化。另外,要维护原序列的值,可以采用树状数组在差分数组上进行单点修改、区间查询即可。

代码如下

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+10;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} int n,m;char s[4];
ll a[maxn],b[maxn],bit[maxn];
inline void change(int pos,ll val){
for(int i=pos;i<=n;i+=i&-i)bit[i]+=val;
}
inline ll get(int pos){
ll ret=0;
for(int i=pos;i;i-=i&-i)ret+=bit[i];
return ret;
}
struct node{
#define ls(o) t[o].lc
#define rs(o) t[o].rc
int lc,rc;ll g;
}t[maxn<<1];
int tot,root;
inline void pushup(int o){t[o].g=gcd(t[ls(o)].g,t[rs(o)].g);}
int build(int l,int r){
int o=++tot;
if(l==r){t[o].g=b[l];return o;}
int mid=l+r>>1;
ls(o)=build(l,mid),rs(o)=build(mid+1,r);
return pushup(o),o;
}
void modify(int o,int l,int r,int pos,ll val){
if(l==r){t[o].g+=val;return;}
int mid=l+r>>1;
if(pos<=mid)modify(ls(o),l,mid,pos,val);
else modify(rs(o),mid+1,r,pos,val);
pushup(o);
}
ll query(int o,int l,int r,int x,int y){
if(l==x&&r==y)return t[o].g;
int mid=l+r>>1;
if(y<=mid)return query(ls(o),l,mid,x,y);
else if(x>mid)return query(rs(o),mid+1,r,x,y);
else return gcd(query(ls(o),l,mid,x,mid),query(rs(o),mid+1,r,mid+1,y));
} void read_and_parse(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),b[i]=a[i]-a[i-1];
root=build(1,n);
}
void solve(){
int l,r;ll delta;
while(m--){
scanf("%s%d%d",s,&l,&r);
if(s[0]=='Q'){
ll c=a[l]+get(l),d=l<r?abs(query(root,1,n,l+1,r)):0;
printf("%lld\n",gcd(c,d));
}
else{
scanf("%lld",&delta);
modify(root,1,n,l,delta);
if(r<n)modify(root,1,n,r+1,-delta);
change(l,delta);
if(r<n)change(r+1,-delta);
}
}
}
int main(){
read_and_parse();
solve();
return 0;
}

【CH4302】Interval GCD的更多相关文章

  1. 【精】iOS GCD 具体解释

    一.介绍 1.什么是GCD? Grand Central Dispatch.是苹果公司开发的一套多核编程的底层API. GCD首次公布在Mac OS X 10.6,iOS4及以上也可用.GCD存在于l ...

  2. 【线段树】Interval GCD

    题目描述 给定一个长度为N的数列A,以及M条指令 (N≤5*10^5, M<=10^5),每条指令可能是以下两种之一: "C l r d",表示把 A[l],A[l+1],- ...

  3. 【数论】二进制GCD

    二进制GCD     GCD这种通用的算法相信每个OLER都会 ,辗转相除,代码只有四行 : int GCD(int a,int b){ if(b==0) return a; return GCD(b ...

  4. 【BZOJ】2818: Gcd(欧拉函数/莫比乌斯)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2818 我很sb的丢了原来做的一题上去.. 其实这题可以更简单.. 设 $$f[i]=1+2 \tim ...

  5. 【单例模式】单例模式 & GCD单例模式 & 将封装单例模式到宏

    懒汉式单例模式 下面的代码块, 基本是单例模式的完整版本了. 可扩展的地方,可以在init方法中作扩展. // static 在全局变量的作用域仅限于当前文件内部 static id _instanc ...

  6. 【HDOJ】3071 Gcd & Lcm game

    刚开始看这个题目,觉得没法做.关键点是数据小于100.因此,可以枚举所有小于100的素因子进行位压缩.gcd就是求最小值,lcm就是求最大值.c++有时候超时,g++800ms.线段树可解. /* 3 ...

  7. 【iOS】多线程GCD

    GCD(Grand Central Dispatch) : 牛逼的中枢调度器.苹果自带,纯C语言实现,提供了许多且强大的函数,它能够提高代码的运行效率与多核的利用率. 一.GCD的基本使用 1.GCD ...

  8. 【推导】zoj3846 GCD Reduce

    题意:给你n个正整数a1...an,一次操作是选择任意两个数ai,aj,将它们都替换成gcd(ai,aj).让你在5n步内将所有数变为1.或者输出不可能. 如果所有数的gcd不为1,显然不可能. 否则 ...

  9. 【BZOJ】【4052】【CERC2013】Magical GCD

    DP/GCD 然而蒟蒻并不会做…… Orz @lct1999神犇 首先我们肯定是要枚举下端点的……嗯就枚举右端点吧…… 那么对于不同的GCD,对应的左端点最多有log(a[i])个:因为每次gcd缩小 ...

随机推荐

  1. 使用synchronized的几种场景

    1.修饰一个方法synchronized 修饰一个方法很简单,就是在方法的前面加synchronized,例如: public synchronized void method() { // todo ...

  2. MySQL之Innodb恢复的学习笔记

    MySQL · 引擎特性 · InnoDB 崩溃恢复过程 enum { SRV_FORCE_IGNORE_CORRUPT = 1, /*!< let the server run even if ...

  3. c/c++ 重载运算符 类型转换运算符

    重载运算符 类型转换运算符 问题:能不能把一个类型A的对象a,转换成另一个类型B的对象b呢?? 是可以的.这就必须要用类型A的类型转换运算符(conversion operator) 下面的opera ...

  4. 基于DataTables实现根据每个用户动态显示隐藏列,可排序

      前言 在后台管理系统开发中,难免会出现列数太多的情况,这里提供一个解决方案:用户设置显示哪些列,每个用户互不影响,并且可以根据用户的习惯设置列的排序. 1.演示 2.html代码说明 3.java ...

  5. RabbitMQ广播:direct模式

    一. 消息的广播需要exchange:exchange是一个转发器,其实把消息发给RabbitMQ里的exchange fanout: 所有bind到此exchange的queue都可以接收消息,广播 ...

  6. c# 日期函数DateTime.ToString()日期的各种格式

    //c# datetime 格式化 DateTime dt = DateTime.Now; //2017/11/14 10:46:56 label1.Text = dt.ToString();//20 ...

  7. springboot2+freemarker简单使用

    一.src/main/resources/templates下新建welcome.ftl <!DOCTYPE html> <html lang="en"> ...

  8. string find()函数

    链接 [https://www.cnblogs.com/wkfvawl/p/9429128.html]

  9. 安装VM-tools

    win10系统 VMware12 Ubuntu64位安装VM-tools时所遇到的提示信息: open-vm-tools are available from the OS vendor and VM ...

  10. C语言之控制语言:分支和跳转

    if语句 #include<stdio.h> int main(void) { const int FREEZING = 0; float temperature; int cold_da ...