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,int y){
13     if(y==0)return x;
14     else return gcd(y,x%y);
15 }
16 void build(int l,int r,int now){
17     tr[now].l=l;tr[now].r=r;
18     if(l==r){
19         tr[now].gcd=a[l];
20         return;
21     }
22     int mid=(l+r)>>1;
23     build(l,mid,now*2);
24     build(mid+1,r,now*2+1);
25     tr[now].gcd=gcd(tr[now*2].gcd,tr[now*2+1].gcd);
26 }
27 void change(int x,int y,int now){
28 //    cout<<tr[now].l<<" "<<tr[now].r<<" "<<x<<endl;
29     if(tr[now].l==x&&tr[now].r==x){
30         tr[now].gcd=y;
31         return ;
32     }
33     int mid=(tr[now].l+tr[now].r)>>1;
34     if(x>mid)change(x,y,now*2+1);
35     else change(x,y,now*2);
36     tr[now].gcd=gcd(tr[now*2].gcd,tr[now*2+1].gcd);
37 }
38 int check(int l,int r,int x,int now){
39     if(tr[now].gcd%x==0)return 0;
40     if(tr[now].l==l&&tr[now].r==r){
41         if(l==r)return 1;
42         if(tr[now*2].gcd%x==0)return check(tr[now*2+1].l,tr[now*2+1].r,x,now*2+1);
43         if(tr[now*2+1].gcd%x==0)return check(tr[now*2].l,tr[now*2].r,x,now*2);
44         return 2;
45     }
46     int mid=(tr[now].l+tr[now].r)>>1;
47     if(l>mid)return check(l,r,x,now*2+1);
48     else if(r<=mid)return check(l,r,x,now*2);
49     else{
50         return check(l,mid,x,now*2)+check(mid+1,r,x,now*2+1);
51     }
52 }
53 int main(){
54     scanf("%d",&n);
55     for(int i=1;i<=n;i++){
56         scanf("%d",&a[i]);
57     }
58     build(1,n,1);
59     scanf("%d",&m);
60     for(int i=1;i<=m;i++){
61         int k;
62         scanf("%d",&k);
63         if(k==1){
64             int l,r,x;
65             scanf("%d%d%d",&l,&r,&x);
66             if(check(l,r,x,1)<=1)printf("YES\n");
67             else printf("NO\n");
68         }
69         else{
70             int x,y;
71             scanf("%d%d",&x,&y);
72             change(x,y,1);
73         }
74     }
75     return 0;
76 }

题意

?给出一段序列(1≤n≤5*105),两个操作(1≤q≤4*105)

?操作1 给出l,r,x

?求区间l-r的gcd,如果至多能改掉区间内的一个数,使gcd是x的倍数,那么输出YES,否则输出NO

?操作2 给出pos,x

?将序列中pos位置上的数字改为x

题解

线段树,维护区间的gcd

因为题目询问删除一个数,我们把整个区间分成两块,如果两边的gcd都是x的倍数显然是可以的,如果都不是gcd的倍数,就不行了,因为使两个gcd的gcd为x的倍数,这两个gcd应该都至少含有x因子。如果一个gcd是x的倍数,一个不是,那就递归处理不是的那个区间。

原文地址:https://www.cnblogs.com/Xu-daxia/p/9306754.html

时间: 2024-11-10 12:45:51

codeforces 914 D 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 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

[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$的倍数就不

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 757B:Bash&#39;s Big Day(分解因子+Hash)

http://codeforces.com/problemset/problem/757/B 题意:给出n个数,求一个最大的集合并且这个集合中的元素gcd的结果不等于1. 思路:一开始把素数表打出来,发现有9k+个数,不能暴力枚举.发现O(sqrt(n)*n)似乎可行,就枚举因子,然后出现过的因子就在Hash[]加1,最后枚举素数表里的元素,找出现次数最多的,因为那些数都可以映射在素数表里面.注意最少的ans是1. 1 #include <cstdio> 2 #include <algo

codeforces水题100道 第八题 Codeforces Round #274 (Div. 2) A. Expression (math)

题目链接:http://www.codeforces.com/problemset/problem/479/A题意:给你三个数a,b,c,使用+,*,()使得表达式的值最大.C++代码: #include <iostream> using namespace std; int a, b, c, ans; int main() { cin >> a >> b >> c; int t = max(a+b, a*b); ans = max(t + c, t * c

Codeforces 914 C Travelling Salesman and Special Numbers

Discription The Travelling Salesman spends a lot of time travelling so he tends to get bored. To pass time, he likes to perform operations on numbers. One such operation is to take a positive integer x and reduce it to the number of bits set to 1 in

Codeforces Round #371 (Div. 1) D. Animals and Puzzle 二维倍增

D. Animals and Puzzle 题目连接: http://codeforces.com/contest/713/problem/D Description Owl Sonya gave a huge lake puzzle of size n × m to hedgehog Filya as a birthday present. Friends immediately started to assemble the puzzle, but some parts of it turn