【CF474F】 Ant colony

题目

题目描述
Mole is hungry again. He found one ant colony, consisting of nn ants, ordered in a row. Each ant ii ( 1<=i<=n1<=i<=n ) has a strength s_{i}s
i

.

In order to make his dinner more interesting, Mole organizes a version of «Hunger Games» for the ants. He chooses two numbers ll and rr ( 1<=l<=r<=n1<=l<=r<=n ) and each pair of ants with indices between ll and rr (inclusively) will fight. When two ants ii and jj fight, ant ii gets one battle point only if s_{i}s
i

divides s_{j}s
j

(also, ant jj gets one battle point only if s_{j}s
j

divides s_{i}s
i

).

After all fights have been finished, Mole makes the ranking. An ant ii , with v_{i}v
i

battle points obtained, is going to be freed only if v_{i}=r-lv
i

=r−l , or in other words only if it took a point in every fight it participated. After that, Mole eats the rest of the ants. Note that there can be many ants freed or even none.

In order to choose the best sequence, Mole gives you tt segments [l_{i},r_{i}] and asks for each of them how many ants is he going to eat if those ants fight.

输入格式
Mole is hungry again. He found one ant colony, consisting of nn ants, ordered in a row. Each ant ii ( 1<=i<=n1<=i<=n ) has a strength s_{i}s
i

.

In order to make his dinner more interesting, Mole organizes a version of «Hunger Games» for the ants. He chooses two numbers ll and rr ( 1<=l<=r<=n1<=l<=r<=n ) and each pair of ants with indices between ll and rr (inclusively) will fight. When two ants ii and jj fight, ant ii gets one battle point only if s_{i}s
i

divides s_{j}s
j

(also, ant jj gets one battle point only if s_{j}s
j

divides s_{i}s
i

).

After all fights have been finished, Mole makes the ranking. An ant ii , with v_{i}v
i

battle points obtained, is going to be freed only if v_{i}=r-lv
i

=r−l , or in other words only if it took a point in every fight it participated. After that, Mole eats the rest of the ants. Note that there can be many ants freed or even none.

In order to choose the best sequence, Mole gives you tt segments [l_{i},r_{i}] and asks for each of them how many ants is he going to eat if those ants fight.

输出格式
Mole is hungry again. He found one ant colony, consisting of nn ants, ordered in a row. Each ant ii ( 1<=i<=n1<=i<=n ) has a strength s_{i}s
i

.

In order to make his dinner more interesting, Mole organizes a version of «Hunger Games» for the ants. He chooses two numbers ll and rr ( 1<=l<=r<=n1<=l<=r<=n ) and each pair of ants with indices between ll and rr (inclusively) will fight. When two ants ii and jj fight, ant ii gets one battle point only if s_{i}s
i

divides s_{j}s
j

(also, ant jj gets one battle point only if s_{j}s
j

divides s_{i}s
i

).

After all fights have been finished, Mole makes the ranking. An ant ii , with v_{i}v
i

battle points obtained, is going to be freed only if v_{i}=r-lv
i

=r−l , or in other words only if it took a point in every fight it participated. After that, Mole eats the rest of the ants. Note that there can be many ants freed or even none.

In order to choose the best sequence, Mole gives you tt segments [l_{i},r_{i}] and asks for each of them how many ants is he going to eat if those ants fight.

题意翻译
给出一个长度为 nn 的序列,qq 组询问

每次给定区间 [l,r][l,r],将 [l,r][l,r] 中的每个数两两比较

如果 a,b \in [l,r]a,b∈[l,r], a|ba∣b 则 aa 得一分, b|ab∣a 则 bb 得一分

问有多少个没有得到满分

输入输出样例
输入 #1复制
5
1 3 2 4 2
4
1 5
2 5
3 5
4 5
输出 #1复制
4
4
1
1
说明/提示
Mole is hungry again. He found one ant colony, consisting of nn ants, ordered in a row. Each ant ii ( 1<=i<=n1<=i<=n ) has a strength s_{i}s
i

.

In order to make his dinner more interesting, Mole organizes a version of «Hunger Games» for the ants. He chooses two numbers ll and rr ( 1<=l<=r<=n1<=l<=r<=n ) and each pair of ants with indices between ll and rr (inclusively) will fight. When two ants ii and jj fight, ant ii gets one battle point only if s_{i}s
i

divides s_{j}s
j

(also, ant jj gets one battle point only if s_{j}s
j

divides s_{i}s
i

).

After all fights have been finished, Mole makes the ranking. An ant ii , with v_{i}v
i

battle points obtained, is going to be freed only if v_{i}=r-lv
i

=r−l , or in other words only if it took a point in every fight it participated. After that, Mole eats the rest of the ants. Note that there can be many ants freed or even none.

In order to choose the best sequence, Mole gives you tt segments [l_{i},r_{i}] and asks for each of them how many ants is he going to eat if those ants fight.

思路

用线段树维护区间gcd和答案
考虑合并
设两个区间的gcd分别为a、b,且a<b,设t=gcd(a,b)
如果t=a那么ans=ansa,如果t=b则ans=ansb
如果t<min(a,b)那么ans=0,如果a=b=t,则ans=ansa+ansb

代码

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int N=2e5+77;
struct node
{
	int gcd;
	node *ls,*rs;
}pool[N * 2];
node *NewNode()
{
	int cnt = 0;
	pool[cnt].gcd = 0,pool[cnt].ls = pool[cnt].rs = NULL;
	return &pool[cnt++];
}
vector<int> v[N];
map<ll,int>f;
int gcd(int x,int y){return y == 0 ? x : gcd(y, x % y);}
int n,m;
ll a[N],b[N];
node *build(int l,int r)
{
	if(l > r)return NULL;
	node *rt = NewNode();
	if(l == r){
		rt->gcd = a[l];
		return rt;
	}
	int mid = l + r >> 1;
	rt->ls = build(l,mid);
	rt->rs = build(mid + 1,r);
	rt->gcd = gcd(rt->ls->gcd,rt->rs->gcd);  
	return rt;
}
int query(node *rt,int l,int r,int L,int R)
{
	if(l > R || r < L || l > r)return 0;
	if(L <= l && r <= R){
		return rt->gcd;
	}
	int ans = 0;
	int mid = l + r >> 1;
	ans = gcd(ans,query(rt->ls,l,mid,L,R));
	ans = gcd(ans,query(rt->rs,mid + 1,r,L,R));
	return ans;
}
void solve(int x,int l,int r)
{
	x = f[x];
	int ans = upper_bound(v[x].begin(),v[x].end(),r) - upper_bound(v[x].begin(),v[x].end(),l - 1);
	printf("%d\n",r - l + 1 - ans);
	return ;
}
int main()
{
	scanf("%d",&n);
	for(int i = 1; i <= n; ++i)
	{
		scanf("%lld",&a[i]);
		b[i]=a[i];
	}
	sort(b+1,b+1+n);
	int siz=unique(b+1,b+1+n)-(b+1);
	for(int i = 1; i <= n; ++i)
	{
		int x=lower_bound(b + 1,b + 1 + siz,a[i]) - b;
		f[a[i]]=x;
		v[x].push_back(i); 
	}
	node *rt=build(1,n);
	scanf("%d",&m);
	for(int i = 1; i <= m; ++i)
	{
		int l,r;
		scanf("%d %d",&l,&r);
		int g = query(rt,1,n,l,r);
		solve(g,l,r);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值