Bash and a Tough Math Puzzle 线段树维护区间gcd

还是一道很不错的题目,很容易想到用一棵线段树来维护区间gcd

注意用倍数来剪枝就好了,很是一到很好的题目的

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;
const int N = 5e5+10;
int n,q;
struct Segment{
	int l,r;
	int d;
}tr[N<<2];

int w[N];
int res;
int gcd(int a,int b){
	return b?gcd(b,a%b):a;
}

void pushup(int u){
	tr[u].d = gcd(tr[u<<1].d,tr[u<<1|1].d);
}

void build(int u,int l,int r){
	tr[u] = {l,r};
	if(l==r){tr[u].d = w[l];return;}
	int mid = l+r>>1;
	build(u<<1,l,mid),build(u<<1|1,mid+1,r);
	pushup(u);
}

void modify(int u,int x,int c){
	if(tr[u].l==tr[u].r&&tr[u].l==x){
		tr[u].d = c;return; 
	}
	
	int mid = (tr[u].l+tr[u].r)>>1;
	if(x<=mid)modify(u<<1,x,c);
	else modify(u<<1|1,x,c);
	pushup(u);
}

void query(int u,int l,int r,int x){
	
	if(res>1)return;
	if(l<=tr[u].l&&tr[u].r<=r){
		if(tr[u].d%x==0)return;
	}
	if(tr[u].l==tr[u].r){
		res+=(tr[u].d%x!=0);
		return;
	}
	
	int mid = tr[u].l+tr[u].r>>1;
	if(l<=mid)query(u<<1,l,r,x);
	if(r>mid)query(u<<1|1,l,r,x);
	
	
}


int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>w[i];
	cin>>q;
	build(1,1,n);
	while(q--){
		int op;cin>>op;
		if(op==1){
			int l,r,x;cin>>l>>r>>x;
			res = 0;
			query(1,l,r,x);
			if(res>1)cout<<"NO"<<"\n";
			else cout<<"YES\n";
			
		}else{
			int x,c;cin>>x>>c;
			modify(1,x,c);
		}
	}
}
相关推荐
王老师青少年编程1 分钟前
csp信奥赛C++高频考点专项训练之贪心算法 --【部分背包问题】:部分背包问题
c++·算法·贪心·csp·信奥赛·部分背包问题
九思十安3 分钟前
HNU2026-算法设计与分析-笔记 3 摊还分析
笔记·算法
无忧.芙桃5 分钟前
现代C++讲解之enum class,static_assert,tuple的使用
开发语言·c++
周杰伦fans7 分钟前
深入 C# 匿名类型:从 `new { Ask = ask }` 说起
开发语言·c#
嘻嘻哈哈樱桃7 分钟前
牛客经典101题题解集--哈希
java·数据结构·python·算法·leetcode·职场和发展·哈希算法
fish_xk10 分钟前
c++中的继承
开发语言·c++
froginwe1112 分钟前
CSS 图像透明/不透明
开发语言
自我意识的多元宇宙13 分钟前
【数据结构】 红黑树
数据结构·算法
wayz1114 分钟前
Day 15 编程实战:KMeans聚类与股票风格分类
算法·机器学习·分类·kmeans·聚类
不知名的老吴16 分钟前
数据结构与算法之排序算法
算法·排序算法