CH 4302 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)。
由《九章算术》中的更相减损我们知道gcd(x,y)=gcd(x,y-x)同理可以推到多个整数。(可以用数学归纳法证明)
因此,构造一个长度为N的新数列B,其中B[i]=A[i]-A[i-1],B[1]为任意值,数列B称作数列A的差分序列。我们可以用线段树维护序列B的区间最大公约数。询问“Q l r”,就等于求出gcd(A[l],ask(1,l+1,r))。
在指令“C l r d”下只有B[l]加d,B[r+1]减d,所以直接线段树两次单点修改即可,对于原序列A,我们之间用树状数组“区间修改,单点查询”维护即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=500010;
struct node{
int l,r;
long long data;
} t[maxn*4];
long long a[maxn],b[maxn],c[maxn];
int n,m,l,r;
long long x;
long long gcd(long long a,long long b) {
return b ? gcd(b,a%b) : a;
}
void build(int p,int l,int r){
t[p].l=l;t[p].r=r;
if(l==r){t[p].data=b[l];return;}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].data=gcd(t[p*2].data,t[p*2+1].data);
}
void change(int p,int x,long long v){
if(t[p].l==t[p].r){t[p].data+=v;return;}
int mid=(t[p].l+t[p].r)/2;
if(x<=mid) change(p*2,x,v);
else change(p*2+1,x,v);
t[p].data=gcd(t[p*2].data,t[p*2+1].data);
}
long long ask(int p,int l,int r){
if(l<=t[p].l&&r>=t[p].r) return abs(t[p].data);
int mid=(t[p].l+t[p].r)/2;
long long val=0;
if(l<=mid) val=gcd(val,ask(p*2,l,r));
if(r>mid) val=gcd(val,ask(p*2+1,l,r));
return abs(val);
}
int lowbit(int x){
return x&-x;
}
long long sum(int x) {
long long tmp=0;
for(;x;x-=lowbit(x)) tmp+=c[x];
return tmp;
}
void add(int x,long long y) {
for(;x<=n;x+=lowbit(x)) c[x]+=y;
}
int main(){
cin >>n>>m;
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
b[i]=a[i]-a[i-1];
}
build(1,1,n);
while(m--){
char str[2];
scanf("%s",str);
scanf("%d %d",&l,&r);
if(str[0]=='Q'){
long long tmp=a[l]+sum(l);
long long val=l<r ? ask(1,l+1,r) : 0;
printf("%lld\n",gcd(tmp,val));
}
else{
scanf("%lld",&x);
change(1,l,x);
if(r<n)change(1,r+1,-x);
add(l,x);
add(r+1,-x);
}
}
return 0;
}
CH 4302 Interval GCD 题解的更多相关文章
- CH 4302 Interval GCD
辗转相减法的扩展 $gcd(x, y, z) = gcd(x, y - x, z - y)$ 当有n个数时也成立 所以构造$a_{i}$的差分数组$b_{i} = a_{i} - a_{i - 1}$ ...
- CH4302 Interval GCD
题意 4302 Interval GCD 0x40「数据结构进阶」例题 描述 给定一个长度为N的数列A,以及M条指令 (N≤5*10^5, M<=10^5),每条指令可能是以下两种之一: &qu ...
- JSOI2009 等差数列 和 算术天才⑨与等差数列 和 CH4302 Interval GCD
等差数列 为了检验学生的掌握情况,jyy布置了一道习题:给定一个长度为N(1≤N≤100,000)的数列,初始时第i个数为vi(vi是整数,−100,000≤vi≤100,000),学生们要按照jyy ...
- CH Round #53 -GCD Path
描述 给定一张N个点的有向图,点i到点j有一条长度为 i/(gcd(i,j))的边.有Q个询问,每个询问包含两个数x和y,求x到y的最短距离. 输入格式 第一行包含两个用空格隔开的整数,N和Q. 接下 ...
- 洛谷 P2568 GCD 题解
原题链接 庆祝一下:数论紫题达成成就! 第一道数论紫题.写个题解庆祝一下吧. 简要题意:求 \[\sum_{i=1}^n \sum_{j=1}^n [gcd(i,j)==p] \] 其中 \(p\) ...
- 【CH4302】Interval GCD
题目大意:给定一个长度为 N 的序列,M 个操作,支持区间加,区间查询最大公约数. 题解: 先来看一个子问题,若是单点修改,区间最大公约数,则可以发现,每次修改最多改变 \(O(logn)\) 个答案 ...
- HDU5726:GCD——题解
题目:hdu的5726 (我原博客的东西,正好整理过来,属于st表裸题) (可以看出我当时有多么的菜--) 这道题写了一遍,然而蒟蒻的我的时间爆炸了-- 于是看了一下学长的代码(顺便在此处%一下学长) ...
- CC DGCD:Dynamic GCD——题解
https://vjudge.net/problem/CodeChef-DGCD https://www.codechef.com/problems/DGCD 题目大意: 给一颗带点权的树,两个操作: ...
- [洛谷2257]YY的GCD 题解
整理题目转化为数学语言 题目要我们求: \[\sum_{i=1}^n\sum_{i=1}^m[gcd(i,j)=p]\] 其中 \[p\in\text{质数集合}\] 这样表示显然不是很好,所以我们需 ...
随机推荐
- Vmware Exsi使用简要说明
界面介绍 Exsi的管理工具可以用vSphere Client来管理虚拟机.管理虚拟的网络交换机.管理物理机的内存.物理机的硬盘.物理机的CPU等资源.界面的大致介绍如下图. 资源分配 创建内存.CP ...
- Java线程池的增长过程
通过ThreadPoolExecutor的方式创建线程池 ThreadPoolExecutor 构造方法: public ThreadPoolExecutor(int corePoolSize, in ...
- WPF中如何禁用空格键(或其他键)
在选择的控件中添加KeyDown event method private void OnKeyDown(object sender, KeyEventArgs e){ if (e.Key == Ke ...
- Qt Socket 收发图片——图像拆包、组包、粘包处理
之前给大家分享了一个使用python发图片数据.Qt server接收图片的Demo.之前的Demo用于传输小字节的图片是可以的,但如果是传输大的图片,使用socket无法一次完成发送该怎么办呢?本次 ...
- requestAnimationFrame 兼容方案
[toc] 编写涉及:css, html, js 在线演示codepen html代码 <div class="roll-box"> <div class=&qu ...
- Java虚拟机——Java内存区域
1.运行时区域 Java虚拟机在执行Java程序的时候会把它管理的内厝划分为若干个不同功能的数据区域,如图所示 首先是程序计数器,程序计数器可以理解为当前程序执行的字节码的行号指示器,计数器中的数据即 ...
- 【PYTHON】语法基础 | 开始使用Python
Python的热度不言而喻,机器学习.数据分析的首选语言都是Python,想要学习Python的小伙伴也很多,我之前也没有认真用过Python,所以也想体验一下它的魅力,索性花了两天集中看了一下它的基 ...
- 什么时候使用redis?什么时候使用memcache?
要清楚为什么,redis具有高可用特性,并且可固化,但特性有时候不能成为选择他的理由,一些业务场景中并不需要这样的特性. 什么时候倾向于选择redis? 1.复杂数据结构 value是哈希,列表, ...
- python学习笔记(2)--列表、元组、字符串、字典、集合、文件、字符编码
本节内容 列表.元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1.列表和元组的操作 列表是我们以后最长用的数据类型之一,通过列表可以最方便的对数据实现最方便的存储.修改等操作 定 ...
- Luogu P1462 && P1951
首先有两个最短路,可以考虑把一个东西拿出来二分,也就是可以二分最小值,但是注意不要用SPFA他死了,可以用Dij跑最短路,再二分,效率会大大提高 1.SPFA #include<bits/std ...