【线段树】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 ...
随机推荐
- 从架构师视角看是否该用Kotlin做服务端开发?
前言 自从Oracle收购Sun之后,对Java收费或加强控制的尝试从未间断,谷歌与Oracle围绕Java API的官司也跌宕起伏.虽然Oracle只是针对Oracle JDK8的升级收费,并释放了 ...
- 51nod1414 冰雕(暴力枚举)
题目是这样的: 1414 冰雕 白兰大学正在准备庆祝成立256周年.特别任命副校长来准备校园的装扮. 校园的中心竖立着n个冰雕.这些雕像被排在一个等分圆上,因此他们形成了一个正n多边形.这些冰雕被顺针 ...
- impdp导入.dmp到oracle
1.创建表空间 create tablespace CCGRP_PRO --表空间名 datafile 'D:\oracleData\test.dbf' --物理文件 表空间数据文件存放路径size ...
- PAT 2014 秋
A 1084 Broken Keyboard 注意大小写即可. #include <cstdio> #include <iostream> #include <algor ...
- [安洵杯 2019]easy_serialize_php
0x00 知识点 PHP反序列化的对象逃逸 任何具有一定结构的数据,只要经过了某些处理而把自身结构改变,则可能会产生漏洞. 参考链接: https://blog.csdn.net/a3320315/a ...
- javascript语法规范和良好的变成习惯
1.1空白和多行书写 1.空白:空格键输入的空白.tab键输入的空白以及回车键输入的空白 2.多行书写,不能将引号内的字符串放到两行,不然容易报错. 1.2点语法 . 点语法表达式由对象开始,接着是一 ...
- c++ 模板联系4
//定义类成员函数特化类型 #include "stdafx.h" #include <iostream> using namespace std; typedef f ...
- 读书笔记 - javascript 高级程序设计 - 第一章 简介
第一章 简介 诞生时间 1995 最初用途 客服端验证 第一版标准 注意是标准 1997年 Ecma-262 一个完整的js实现由三部分组成 ECMAScript DOM 文档对象模型 BO ...
- python控制鼠标键盘
1.安装类库 pip install pyautogui 2.代码: import pyautogui,time,random pyautogui.PAUSE = pyautogui.FAILSAFE ...
- 进度3_家庭记账本App_Fragment使用SQLite实现简单存储及查询
AddFragment.java: package com.example.familybooks; import android.content.ContentValues; import andr ...