[CF914D]Bash and a Tough Math Puzzle

给定一个数列$a_1,a_2,...,a_n$?,支持两种操作

1 l r x,猜测数列中[l,r]位置上的数的最大公约数$x$,判断这个猜测是否是接近正确的。如果我们可以在数列[l,r]位置中改动至多一个数使得它们的最大公约数是x,那么这个猜测就被认为是接近正确的(注意我们不需要在数列中进行实际的改动)。如果这个猜测是接近正确的,输出"YES",否则输出"NO"(都不含引号)。

2 i y,将$a_i$的数值改为y。

如果这一段区间有超过一个数不是$x$的倍数就不行了,按照这一条直接写就行了,把gcd打错真是蠢哭

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define M 500010
 5 #define ls node<<1
 6 #define rs node<<1|1
 7 using namespace std;
 8
 9 int n,q;
10 int val[M<<2],a[M];
11
12 int gcd(int x,int y) {return y==0?x:gcd(y,x%y);}
13
14 void update(int node)
15 {
16     if(!val[ls]||!val[rs]) val[node]=val[ls]+val[rs];
17     else val[node]=gcd(val[ls],val[rs]);
18 }
19
20 void build(int node,int l,int r)
21 {
22     if(l==r) {val[node]=a[l];return;}
23     int mid=(l+r)/2;
24     build(ls,l,mid);build(rs,mid+1,r);
25     update(node);
26 }
27
28 int query(int node,int l,int r,int l1,int r1,int x)
29 {
30     if(l1<=l&&r1>=r)
31     {
32         if(val[node]%x==0) return 0;
33         if(l==r) return (val[node]%x!=0);
34     }
35     if(l1>r||r1<l) return 0;
36     int ans=0;
37     int mid=(l+r)/2;
38     ans+=query(ls,l,mid,l1,r1,x);
39     if(ans>1) return ans;
40     return ans+query(rs,mid+1,r,l1,r1,x);
41 }
42
43 void change(int node,int l,int r,int x,int k)
44 {
45     if(l==r) {val[node]=k;return;}
46     int mid=(l+r)/2;
47     if(x<=mid) change(ls,l,mid,x,k);
48     else change(rs,mid+1,r,x,k);
49     update(node);
50 }
51
52 int main()
53 {
54     scanf("%d",&n);
55     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
56     build(1,1,n);
57     scanf("%d",&q);
58     while(q--)
59     {
60         int opt;
61         scanf("%d",&opt);
62         if(opt==1)
63         {
64             int l,r,x;scanf("%d%d%d",&l,&r,&x);
65             printf(query(1,1,n,l,r,x)>1?"NO\n":"YES\n");
66         }
67         else
68         {
69             int x,k; scanf("%d%d",&x,&k);
70             change(1,1,n,x,k);
71         }
72     }
73     return 0;
74 }

原文地址:https://www.cnblogs.com/Slrslr/p/9738151.html

时间: 2024-08-30 11:44:58

[CF914D]Bash and a Tough Math Puzzle的相关文章

Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论

Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论 题意 给你一段数,然后小明去猜某一区间内的gcd,这里不一定是准确值,如果在这个区间内改变一个数的值(注意不是真的改变),使得这个区间的gcd是小明所猜的数也算小明猜对.另一种操作就是真的修改某一点的值. 解题思路 这里我们使用线段树,维护区间内的gcd,判断的时候需要判断这个区间的左右子区间的gcd是不是小明猜的数的倍数或者就是小明猜的数,如果是,那么小明猜对了.否则就需要进入这个区间

Codecraft-18 and Codeforces Round #458:D,Bash and a Tough Math Puzzle

题目传送门 题目大意:Bash喜欢对数列进行操作.第一种操作是询问l~r区间内的gcd值是否几乎为x,几乎为表示能否至多修改一个数达到.第二种操作是将ai修改为x.总共Q个询问,N个数. Solution:简单来说,就是对区间gcd值的维护,使用线段树实现. code: #include <cstdio> using namespace std; int read() { char c;while(c=getchar(),c<'0'||c>'9'); int x=c-'0';whi

codeforces 914 D Bash and a Tough Math Puzzle

1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cstdio> 6 using namespace std; 7 const int N=500100; 8 int n,a[N],m; 9 struct tree{ 10 int l,r,gcd; 11 }tr[N*5]; 12 int gcd(int x,in

914D Bash and a Tough Math Puzzle

传送门 分析 用线段树维护区间gcd,每次查询找到第一个不是x倍数的点,如果这之后还有gcd不能被x整除的区间则这个区间不合法 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib>

Codeforces 914D - Bash and a Tough Math Puzzle 线段树,区间GCD

题意: 两个操作, 单点修改 询问一段区间是否能在至多一次修改后,使得区间$GCD$等于$X$ 题解: 正确思路; 线段树维护区间$GCD$,查询$GCD$的时候记录一共访问了多少个$GCD$不被X整除的区间即可,大于一个就NO 要注意的是,如果真的数完一整个区间,肯定会超时,因此用一个外部变量存储数量,一旦超过一个,就停止整个查询 #include <bits/stdc++.h> #define endl '\n' #define ll long long #define IO ios::s

Codecraft-18 and Codeforces Round #458 C dp D 线段树

Codecraft-18 and Codeforces Round #458 C. Travelling Salesman and Special Numbers 题意: 一个由0.1 组成的数 n,操作:n 有 m 个 1,就把 n 变为 m. 问 <=n 的数中有多少个恰好经过 k 次操作能变为 1. tags:  dp[i][j] 表示长度为 i 且有 j 个 1  的串,比对应的 n 要小的方案数. #include<bits/stdc++.h> using namespace

五猴分桃通解公式-敬献给诺贝尔奖获得者李政道博士

摘要:"五猴分桃问题"是一个中.外非常有名的趣味数学难题.研究这种类型题的简易计算方法曾困扰住了一些大物理学家和数学家.李政道博士在中国科技大学讲学时也特意提到此题, 本文通过对该问题的分析,推导出了能求解所有这种类型题的最简易通解公式 y=a(a/m)n-1-db/c,以及它的姊妹公式: y=[ka(a/m)n-1-db]/c,以及这两个公式有解和无解的条件,使这个问题得到了较园满的解决. Summary: "Five monkey peach assignment pro

51nod 1066 Bash游戏 V2 博弈

1067 Bash游戏 V2 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 有一堆石子共有N个.A B两个人轮流拿,A先拿.每次只能拿1,3,4颗,拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出N,问最后谁能赢得比赛. 例如N = 2.A只能拿1颗,所以B可以拿到最后1颗石子. Input 第1行:一个数T,表示后面用作输入测试的数的数量.(1 <= T <= 10000) 第2 - T + 1行:每行1个

51nod 1068 Bash游戏 V3 博弈

1068 Bash游戏 V3 题目来源: Ural 1180 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 有一堆石子共有N个.A B两个人轮流拿,A先拿.每次拿的数量只能是2的正整数次幂,比如(1,2,4,8,16....),拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出N,问最后谁能赢得比赛. 例如N = 3.A只能拿1颗或2颗,所以B可以拿到最后1颗石子.(输入的N可能为大数) Input 第1行:一个