C-小红的数组查询(二)_牛客周赛 Round 95
思路:不难看出a数组是有循环的
d=3,p=4时,a数组:1、0、3、2、1、0、3、2....... 最小循环节为4,即最多4种不同的数
d=4,p=6时,a数组:1、5、3、1、5、3.......最小循环节为3
d=4,p=10时,a数组:1、5、9、3、7、1、5、9、3、7.......最小循环节为5
可以得出,最小循环节T=p / gcd(d,p)
ans=min(询问的区间长度,最小循环节)
ans=min(r-l+1,T)
特殊情况:p=1时,a数组:1、0、0、0........(任何数对1取模均为0)
l=1,r>1时,ans=2
其余,ans=1
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ll d,p,q;
cin>>d>>p>>q;
// 将d对p取模,因为后续的计算是基于模p的
d = d % p;
// 计算d和p的最大公约数g
ll g = __gcd(d, p);
// 计算T,即周期长度,T = p / g
ll T = p / g;
// 处理q次询问
while (q--) {
ll l, r;
cin >> l >> r;
// 特殊情况:如果p == 1,那么所有元素都是0(因为任何数mod 1都是0)
if (p == 1) {
// 如果区间长度大于1,那么只有0和1两种元素(因为a1=1,其他都是0)
ll ans = 1;
if (l == 1 && r > 1) {
ans++;
}
cout << ans << endl;
continue;
}
// 计算区间内的元素种类数
// 如果区间长度小于T,那么元素种类数就是区间长度,
// 否则,元素种类数就是T
cout << min(r - l + 1, T) << endl;
}
}