CF474F Ant colony

线段树求GCD

我除了我被吓蒙了还能说啥

先帮我看一眼这两份gcd有什么区别

int gcd(int a,int b)
{
    if (a%b==0) return b;
    else return gcd(b,a%b)
}
int gcd(int a,int b)
{
    if (!b) return a;
    else return gcd(b,a%b)
}

一份AC一份RE

我们线段树维护区间GCD然后用一个pair记录数字的位置以及本身,之后查到区间GCD后,在pair里二分一下就好了

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=1e5+10;
struct Seg
{
	int bo[2],so[2],g;
}t[M<<4];
int num[M],tot=0;
int n,cnt=1,rt,m;
typedef pair<int, int> pii;
pii ans[M];
inline int read()
{
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x; 
} 
inline int gcd(int a,int b)
{
	if (!b) return a;
	return gcd(b,a%b);	
} 
inline void pushup(int x)
{
	int ls=t[x].so[0];
	int rs=t[x].so[1];
	t[x].bo[0]=t[ls].bo[0];
	t[x].bo[1]=t[rs].bo[1];
	t[x].g=gcd(t[ls].g,t[rs].g);
	return ; 
} 
inline void built(int l,int r,int x)
{
	if (l==r) 
	{
		scanf("%d",&ans[++tot].first);
		ans[tot].second=tot;
		t[x].bo[0]=t[x].bo[1]=l;
		t[x].so[0]=t[x].so[1]=-1;
		return (void)(t[x].g=ans[tot].first);
	}
	int mid=(l+r)>>1;
	t[x].so[0]=++cnt;t[x].so[1]=++cnt;
	built(l,mid,t[x].so[0]);built(mid+1,r,t[x].so[1]);
	pushup(x);
	return ;
}
inline int query(int l,int r,int x)
{
	if (l<=t[x].bo[0]&&t[x].bo[1]<=r) return t[x].g;
	int mid=(t[x].bo[0]+t[x].bo[1])>>1;int a1=0,a2=0;
	if (l<=mid) a1=query(l,r,t[x].so[0]);
	if (r>mid) a2=query(l,r,t[x].so[1]);
	return gcd(a1,a2);
}
int main()
{
	n=read();
	built(1,n,rt);int l,r;
	m=read();
	sort(ans+1,ans+n+1);
	for (int i=1;i<=m;i++)
	{
		l=read();r=read();int G=query(l,r,rt);
		int a=lower_bound(ans+1,ans+n+1,pii(G,l))-(ans+1);
		int b=lower_bound(ans+1,ans+n+1,pii(G,r+1))-(ans+1);
		cout<<(r-l+1)-(b-a)<<endl;
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/81014874
ANT