cf914D. Bash and a Tough Math Puzzle(线段树)

题意

题目链接

Sol

直接在线段树上二分

当左右儿子中的一个不是$x$的倍数就继续递归

由于最多递归到一个叶子节点,所以复杂度是对的

开始时在纠结如果一段区间全是$x$的两倍是不是需要特判,实际上是不需要的。

可以这么想,如果能成功的话,我们可以把那个数改成$1$,这样比$x$大的数就不会对答案产生影响了。

不过我的线段树为啥要开6倍空间才能过。。真是狗血、、

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e6 + 10, INF = 1e9 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-')f =- 1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, M, a[MAXN];
#define ls k << 1
#define rs k << 1 | 1 
struct Node {
    int l, r, g;
}T[MAXN];
int gcd(int a, int b) {
    return (b == 0 ? a : gcd(b, a % b));
}
void update(int k) {
    T[k].g = gcd(T[ls].g, T[rs].g);
}
void Build(int k, int ll, int rr) {
    T[k] = (Node) {ll, rr};
    if(ll == rr) {T[k].g = a[ll]; return ;}
    int mid = T[k].l + T[k].r >> 1;
    Build(ls, ll, mid); Build(rs, mid + 1, rr);
    update(k);
}
void PointChange(int k, int pos, int val) {
    if(T[k].l == T[k].r) {T[k].g = val; return ;}
    int mid = T[k].l + T[k].r >> 1;
    if(pos <= mid) PointChange(ls, pos, val); 
    else PointChange(rs, pos, val);
    update(k);
}
int sum = 0;
void IntervalTims(int k, int ll, int rr, int val) {
    if(sum > 1) return ;
    if(T[k].l == T[k].r) sum++;
    int mid = T[k].l + T[k].r >> 1;
    if(ll <= mid && (T[ls].g % val)) IntervalTims(ls, ll, rr, val);
    if(rr  > mid && (T[rs].g % val)) IntervalTims(rs, ll, rr, val);
}
main() {
    N = read();
    for(int i = 1; i <= N; i++) a[i] = read();
    Build(1, 1, N);
    M = read();
    while(M--) {
        int opt = read();
        if(opt == 1) {
            int l = read(), r = read(), x = read();
            sum = 0; IntervalTims(1, l, r, x);
            puts(sum > 1 ? "NO" : "YES");
        } else {
            int pos = read(), x = read();
            PointChange(1, pos, x);
        }
    }
}
/*
*/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IMWeb前端团队

JS中的非可变性

非可变性是函数式编程的一个核心规则,对于面向对象编程也有很多用处。本文为参考sitepoint(参考链接1)中的文章后所记录的一些主要内容。 参考链接1:...

19550
来自专栏desperate633

LintCode 简化路径题目分析代码

思路比较简单,遇到..就回到上一级,遇到.或者空就不处理。 我们使用一个队列来处理,同时将三个需要特殊处理的字符存到一个set里面

6910
来自专栏一枝花算不算浪漫

Java中常见数据结构Set之HashSet

32860
来自专栏Golang语言社区

用Golang写一个搜索引擎

本篇较长较枯燥,请保持耐心看完。 前面两章介绍了一下倒排索引以及倒排索引字典的两种存储结构,分别是 跳跃表 和 哈希表 ,本篇我们介绍另一种数据结构,他也被大量...

47570
来自专栏数据结构与算法

洛谷P3178 [HAOI2015]树上操作

题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a 。操作 2 :把某个节...

36280
来自专栏猿人谷

(重点)链式栈

顺序栈的实现在于使用了数组这个基本数据结构,数组中的元素在内存中的存储位置是连续的,且编译器要求我们在编译期就要确定数组的大小,这样对内存的使用效率并不高,一来...

23690
来自专栏编程之旅

线性表的顺序存储结构

举个简单的例子,蔺老师在给九班学生安排座位之前,会让学生们从矮到高按照身高的高矮升序排列,假如蔺老师的班上只有十个学生,而全班共有50个座位,那蔺老师会把这10...

18320
来自专栏开发与安全

数据结构:队列的顺序存储结构(循环队列)

队列(Queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。是一种先进先出的线性表(FIFO)。允许插入的一端称为队尾,允许删除的一端称为队头...

24870
来自专栏mySoul

java队列

队列为特殊的线性表,队列的特点先进先出(FIFO),队列插入为入队,队列删除为出对。

28900
来自专栏java一日一条

Java编程常见问题汇总3

这里本意是希望用当前类来加载希望的对象, 但是这里的getClass()可能抛出异常, 特别在一些受管理的环境中, 比如应用服务器, web容器, Java W...

8620

扫码关注云+社区

领取腾讯云代金券