P8809 [蓝桥杯 2022 国 C] 近似 GCD 题解

考虑到非常困难。再简单的计数题也要认真看一眼。

P8809 [蓝桥杯 2022 国 C] 近似 GCD

思路

考虑刻画充要条件去计数。发现一个子区间合法的充要条件是至多一个数不是 \(g\) 的倍数。

将不是 \(g\) 倍数的东西看作 1,否则看作 0,合法充要条件是区间和小于等于 1。

于是双指针类似贪心的去做即可。对于每一个位置当作左端点然后记其合法的最右边的位置。

code

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
typedef unsigned long long ll;
int a[N],colcnt=0,f[N];
ll cnt[N];
int n,g;
bool bei[N];
int main()
{
	cin>>n>>g;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	int t=n+1;f[n+1]=n+1;
	for(int i=n;i>=1;i--)
	{
		f[i]=t;if(a[i]%g!=0) t=i;
	}
	for(int i=1;i<=n;i++)
	{
		if(!(a[i]%g)) f[i]=f[f[i]];
	}
	ll ans=0;
	for(int i=1;i<=n;i++) ans+=f[i]-i-1;
	cout<<ans<<endl;
}
posted @ 2025-11-21 19:35  all_for_god  阅读(19)  评论(0)    收藏  举报