P8809 [蓝桥杯 2022 国 C] 近似 GCD
题目描述
小蓝有一个长度为 nnn 的数组 A=(a1,a2,⋯ ,an)A = (a_1,a_2,\cdots,a_n)A=(a1,a2,⋯,an),数组的子数组被定义为从原数组中选出连续的一个或多个元素组成的数组。数组的最大公约数指的是数组中所有元素的最大公约数。如果最多更改数组中的一个元素之后,数组的最大公约数为 ggg,那么称 ggg 为这个数组的近似 GCD。一个数组的近似 GCD 可能有多种取值。
具体的,判断 ggg 是否为一个子数组的近似 GCD 如下:
- 如果这个子数组的最大公约数就是 ggg,那么说明 ggg 是其近似 GCD。
- 在修改这个子数组中的一个元素之后(可以改成想要的任何值),子数组的最大公约数为 ggg,那么说明 ggg 是这个子数组的近似 GCD。
小蓝想知道,数组 AAA 有多少个长度大于等于 222 的子数组满足近似 GCD 的值为 ggg。
输入格式
输入的第一行包含两个整数 n,gn,gn,g,用一个空格分隔,分别表示数组 AAA 的长度和 ggg 的值。
第二行包含 nnn 个整数 a1,a2,⋯ ,ana_1,a_2,\cdots,a_na1,a2,⋯,an,相邻两个整数之间用一个空格分隔。
输出格式
输出一行包含一个整数表示数组 AAA 有多少个长度大于等于 222 的子数组的近似 GCD 的值为 ggg。
输入输出样例 #1
输入 #1
5 3
1 3 6 4 10
输出 #1
5
说明/提示
【样例说明】
满足条件的子数组有 555 个 :
[1,3][1,3][1,3]:将 111 修改为 333 后,这个子数组的最大公约数为 333,满足条件。
[1,3,6][1,3,6][1,3,6]:将 111 修改为 333 后,这个子数组的最大公约数为 333,满足条件。
[3,6][3,6][3,6]:这个子数组的最大公约数就是 333,满足条件。
[3,6,4][3,6,4][3,6,4]:将 444 修改为 333 后,这个子数组的最大公约数为 333,满足条件。
[6,4][6,4][6,4]:将 444 修改为 333 后,这个子数组的最大公约数为 333,满足条件。
【评测用例规模与约定】
对于 20%20\%20% 的评测用例,2≤n≤1002\le n\le1002≤n≤100;
对于 40%40\%40% 的评测用例,2≤n≤10002\le n\le10002≤n≤1000;
对于所有评测用例,2≤n≤1052\le n\le10^52≤n≤105,1≤g,ai≤1091\le g,a_i \le10^91≤g,ai≤109。
蓝桥杯 2022 国赛 C 组 F 题。
C++实现
#include<cstdio>
int n,g,a[100001],x;
long long ans;
int upper(int l,int r,int x){
int mid;
for(;l<=r;){
mid=(l+r)>>1;
if(a[mid]<=x)l=mid+1;
else r=mid-1;
}
return l;
}
int main(){
scanf("%d%d",&n,&g);
for(int i=1;i<=n;++i){
scanf("%d",&x);
if(x%g)a[i]=1;
a[i]+=a[i-1];
}
for(int i=1;i<n;++i)
ans+=upper(i+1,n,a[i-1]+1)-i-1;
printf("%lld\n",ans);
return 0;
}
后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容