您的位置:首页 > 运维架构 > Shell

Codeforces 914D - Bash and a Tough Math Puzzle 【线段树】

2018-03-16 17:17 621 查看
D. Bash and a Tough Math Puzzle
time limit per test 
2.5 seconds
memory limit per test     
256 megabytes

Bash likesplaying with arrays. He has an array
a1, a2, ...
an
of n
integers. Helikes to guess the greatest common divisor (gcd) of different segments of thearray. Of course, sometimes the guess is not correct. However, Bash will besatisfied if his guess is
almost correct.

Suppose heguesses that the gcd of the elements in the range
[l, r]
of a
is x.
He considers the guess to be almost correct if he can change at most
one element in the segment such that thegcd of the segment is x
after makingthe change. Note that when he guesses, he doesn't actually change the array —he just wonders if the gcd of the segment can be made
x.
Apart from this, he also sometimes makes changes to the array itself.

Since he can'tfigure it out himself, Bash wants you to tell him which of his guesses arealmost correct. Formally,
you have to process q
queries of one of the following forms:

·  1 l r x
— Bash guesses that the gcd of the range [l, r]
is x.
Report if thisguess is almost correct.

·  2 i y
— Bash sets ai
to y.

Note:
The array is 1-indexed.
Input

The first linecontains an integer
n
(1 ≤ n ≤ 5·105)
 — the size of the array.

The second linecontains
n
integers a1, a2, ..., an
(1 ≤ ai ≤ 109)
 — the elements of the array.

The third linecontains an integer
q
(1 ≤ q ≤ 4·105)
 — the number of queries.

The next
q
lines describe the queries and may have one of the following forms:

·  1 l r x
(1 ≤ l ≤ r ≤ n, 1 ≤ x ≤ 109).

·  2 i y
(1 ≤ i ≤ n, 1 ≤ y ≤ 109).

Guaranteed, thatthere is at least one query of first type.
Output
For each query of first type, output
"YES"
(without quotes) if Bash's guess is almost correct and "NO"
(without quotes) otherwise.
Examples
Input

3

2 6 3

4

1 1 2 2

1 1 3 3

2 1 9

1 1 3 2
Output

YES

YES

NO
Input

5

1 2 3 4 5

6

1 1 4 2

2 3 6

1 1 4 2

1 1 5 2

2 5 10

1 1 5 2
Output

NO

YES

NO

YES
Note

In the first sample, the array initially is
{2, 6, 3}.

For query
1,
the first two numbers already have their gcd as 2.

For query
2,
we can achieve a gcd of 3
by changing thefirst element of the array to 3.
Note that thechanges made during queries of type 1
are temporary and do not get reflected in the array.

After query
3,
the array is now {9, 6, 3}.
For query
4,
no matter which element you change, you cannot get the gcd of the rangeto be
2.

 

【题意】

给出n个数,现在有两种操作

1 x y val 查询【x,y】区间内的数的gcd是否为val,最多允许修改区间内的一个数(若修改操作结束后复原)

2 pos val 将a【pos】的值改为val

【思路】

线段树变形,只要判断下询问过程中区间内多少个数不是val的倍数即可。

#include <cstdio>
#include <bits/stdc++.h>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1

typedef long long ll;
const int maxn = 500005;
const ll mod = 1e9+7;
const ll INF = 1e18;
const double eps = 1e-6;

int n,q,cnt;
int tree[maxn<<2];

int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}

void pushup(int rt)
{
tree[rt]=gcd(tree[rt<<1],tree[rt<<1|1]);
}

void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&tree[rt]);
return;
}
int mid=(l+r)/2;
build(lson);
build(rson);
pushup(rt);
}

void update(int l,int r,int rt,int pos,int val)
{
if(l==r)
{
tree[rt]=val;
return;
}
int mid=(l+r)/2;
if(pos<=mid) update(lson,pos,val);
else update(rson,pos,val);
pushup(rt);
}

void query(int l,int r,int rt,int L,int R,int val)
{
if(cnt==2) return;
if(l==r)
{
if(tree[rt]%val) cnt++;
return;
}
int mid=(l+r)/2;
if(L<=mid&&tree[rt<<1]%val) query(lson,L,R,val);
if(mid<R&&tree[rt<<1|1]%val) query(rson,L,R,val);
}

int main()
{
scanf("%d",&n);
build(1,n,1);
scanf("%d",&q);
while(q--)
{
int op,x,y,val;
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
cnt=0;
scanf("%d",&val);
query(1,n,1,x,y,val);
if(cnt<=1) puts("YES");
else puts("NO");
}
else update(1,n,1,x,y);
}
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息