题目描述
给定x和m,问在区间[a,b]上存在多少个i,使得xi % 1000 = m。
输入
输入由多组数据构成。
每组数据一行,由四个空格分开的整数x、m、a和b组成。
0 <= x, m <= 1000000000
1 <= a <= b <= 1000000000
输出
每组输入数据产生一行输出,即使得上述等式成立的i的个数。
样例输入
13 13 1 100
13 12 1 100
13 13 1 1000000000
样例输出
1
0
10000000
##题解
- i∈(a,b),(b)max=1000000000.肯定要用到快速幂并且取模1000;
- 取模1000,很明显的知道,m的取值范围为(0,999)。所以∀m>=1000,ans=0;
- 验证规律性。
int x=13
int a=1,b=200;
for(int i=a;i<=b;i++){
cout<<pow_mod(x,i,1000)<<",";
}
13,169,197,561,293,809,517,721,373,849,37,481,253,289,757,841,933,129,677,801,413,369,797,361,693,9,117,521,773,49,637,281,653,489,357,641,333,329,277,601,813,569,397,161,93,209,717,321,173,249,237,81,53,689,957,441,733,529,877,401,213,769,997,961,493,409,317,121,573,449,837,881,453,889,557,241,133,729,477,201,613,969,597,761,893,609,917,921,973,649,437,681,853,89,157,41,533,929,77,1,13,169,197,561,293,809,517,721,373,849,37,481,253,289,757,841,933,129,677,801,413,369,797,361,693,9,117,521,773,49,637,281,653,489,357,641,333,329,277,601,813,569,397,161,93,209,717,321,173,249,237,81,53,689,957,441,733,529,877,401,213,769,997,961,493,409,317,121,573,449,837,881,453,889,557,241,133,729,477,201,613,969,597,761,893,609,917,921,973,649,437,681,853,89,157,41,533,929,77,1,
看出每隔100个数就会出现一次13。可能这个时候你会觉得答案就在眼前,但结果告诉你“答案错误”,因为并不是所有的数每隔100次就出现一次,也不是每个数就会多次出现。
不信再试试n=2,它的前几项里,2和4是只出现一次的,只有从数字8开始才出现的循环。分析到这里基本够了。
还有一个可以证明的是,如果一个数在200次内没有出现重复的数,他就不会有重复的数了。
- 编程的实现问题,①m>=1000,输出ans=0。②0< m<1000,算出m重复出现的间隔,不重复出现输出0,有间隔则输出[a,b]区间内能满足的次数。
代码
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long ll;
// (a-2b)(c^2-3ad+d^3)=0
int main()
{
ll n, ans;
while(~scanf("%lld",&n)){
ll a, c, d;
ans = n / 2;//有多少组a=2b的解
ans *= n * n;//a=2b后,因为cd可以任意取1~n,
ll maxd=sqrt(3*n+1);//3*d-d*d*d<=c*c
for(d = 1; d<=maxd; d++)//限制d范围
for(c = 1; c <= n; c++){//对c^2-3ad+d^3=0的解枚举
a = d * d * d + c * c;
if(a % (3 * d) == 0){
a/=(3 * d);
//printf("%d %d %d\n",c,d,a);
if(a>=1 && a <= n){
ans += n;
if(a % 2 == 0)//a为偶数,即减去已算过的a=2b的数
ans--;
}
}
}
printf("%lld\n",ans);
}
}