/*
跟我念三遍:考虑端点!考虑端点!考虑端点!
题目的意思就是要么*2 要么*2-1 找规律之后发现其实是连着的 然后就可以递推出表达式,是连着的
啊.. 题目有坑,可是什么是坑(以后为了格式直接写网页里面.. 记事本排版太丑-.-)
(1)【最大和最小 最大和最小】
把1e18考虑到了之后。。
(好像,如果前面样例过了的话一般后面是没什么特别大的问题,但是会,在很大的数据面前跑不出来)
【很多时候我写的代码跑不出来是因为跑不出来,而不是超时了!(什么的)】
而且!!!最小处的坑,可能是 给到了0,或者给到了1
给到了0,或者给到了1(我去找个人改个备注名。。)
(2)
-。- 怎么还会有,取模的是1e9+7,给的是1e9+6这种辣鸡数据-。-。。。。。。。。
【怎么会给取模边界的数据啊啊啊啊!!!!
-。-自己写的数据不对。。
因为,数据给了1e9,乘以2不会有问题,是我多虑了_(:з」∠)_
那么,为什么要取模?
[1]因为给出答案的时候要取模!
[2]前面*2并不会超出范围,然后有的时候会有误差!
有的时候会有误差!
(图片)
... 想想为什么会有取模的误差
这个取模...
啊。给出的数据是在1e9范围内所以x不用取模,但是乘以2
之后有可能超出题目要求范围
因为一旦有什么可能性就可能溢出。。明白了_(:з」∠)_
x是题目里给的,当然不会溢出啦
对于992B,很重要的就是最大公约数和最小公倍数。。。代码里都有(x)
copy别人的说明。。:
(参考https://blog.csdn.net/becky_w/article/details/80733056以及https://blog.csdn.net/Haipai1998/article/details/80737815)
题目大意,给你区间[l,r]和x,y 问你区间中有多少个数对 (a,b) 使得 gcd(a,b)=x lcm(a,b)=y
a,b交换位置就是不同的数对
1≤l,r≤1e9◂,▸1≤l,r≤1e9 and 1≤x,y<1e9◂,▸1≤x,y<1e9
题目分析,根据lcm(最小公倍数) 的定义 y=a*b/x;
也就是说 x∗y=a∗b◂=▸x∗y=a∗b
那么 ,我们发现a,b一定为Y的因数,所以我们枚举y的每个因子就可以,我们只要用log(y)的复杂度暴力算每一个因数就可以
然后对于每个因子当做a,
b=x*y/a;
然后判断a,b是否在区间内,gcd(a,b)是否为x
题意:求区间[L,R]内有多少对数<a,b>,使得gcd(a,b)==x,lcm(a,b)==y. 其中L,R,a,b都已经给定. 如果<a,b>中a==b只算一种
思路:既然是y的因数,可以在sqrt(y)的时间内处理出所有因数个数t(t很小),暴力t^2
关于因数个数很小的解释: 根据质因数分解唯一定理,每个质因数的幂次不会太大,因子总个数=(k1+1)*(k2+1)-----等等. 因此一个数的因子总个数不会太多.碰到类似和因子有关的内容直接暴力
但是自己写的时候遇到一点困难。。。
然后在check里重新算ll b = x * y / a; 就不会遗漏了_(:з」∠)_
不想写了。。太懒了。。。。。
。。。。。。。。。。。。。打农药去了。。。。
18-7-9
【星号】快速幂!
记住快速幂!
//a是底数,b是指数,mode是取模数,sum是记录取模的结果
long long Mode(long long a, long long b, long long mode)
{
long long sum = 1;
while (b) {
if (b & 1) {
sum = (sum * a) % mode;
b--;
}
b /= 2;
a = a * a % mode;
}
return sum;
}
快速幂参考 https://blog.csdn.net/dbc_121/article/details/77646508
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const ll modd = 1e9 + 7;
//a是底数,b是指数,mode是取模数,sum是记录取模的结果
long long Mode(long long a, long long b, long long mode)
{
long long sum = 1;
while (b) {
if (b & 1) {
sum = (sum * a) % mode;
b--;
}
b /= 2;
a = a * a % mode;
}
return sum;
}
int main(){
ll x; ll k;
while (cin >> x >> k) {
// k is the month;
//k is 1 我怎么把set和mod都忘了..
if (k == 0)cout << (2 * (x%modd) % modd)<<endl;
else if (x == 0)cout << 0 << endl;
else {
//x = x % modd;
ll temp = (2 * x - 1) % modd;
ll summ=Mode(2, k - 1, modd);
//???? 100*100 在100,00的精度之下不会溢出啊....
//敏感度吧-.- 100*2没事,100&100也没事,为什么我想了一会高精度算法
temp = (temp * summ)%modd;
temp = (2 * temp + 1) % modd;
cout << temp << endl;
}
}
return 0;
}
B题
#include<iostream>
#include<algorithm>
#include<set>
#include<math.h>
using namespace std;
typedef long long ll;
const ll modd = 1e9 + 7;
ll a, b, x, y,l,r;
ll gcd(int a, int b)
{
if (a == 0) return b;
else
return gcd(b % a, a);
}
ll lcm(int a, int b)
{
return a * b / gcd(a, b);
}
bool check(ll a){//ll b, ll x, ll y) {
ll b = x * y / a;//【前面说的就是这里!】
//cout << endl;
//cout << "a " << a << endl;
//cout << "b " << b << endl;
//cout << gcd(a, b) << endl;
//cout << endl;
if (a > r || a < l)return false;
else if (b > r || b < l)return false;
else if (gcd(a, b) != x)return false;
//else if (lcm(a, b) != y)return false;
else return true;
}
int main(){
while (cin >> l >> r>>x>>y) {
ll ans = 0;
//mod 1 寻找质数 记得是i*i 以及要有等号!!
if (x == y) {
if (x > r || y < l)cout << "0" << endl;
else if (x > r || y < l)cout << "0" << endl;
else cout << "1" << endl;
return 0;
}
for (ll i = 1; i*i <= y; i++) {
if (y%i == 0) {//如果是0.. 那就是..
/*
//!!!!...
//a=y/i;
b = x * y / i;
//....... 小不忍则乱大谋.......
///......我能说什么.... 这样就忽略了 3 3这种
//因为自己和自己... 自己不会判断为自己的质数,所以判断不到,所以会少一种
//我:???? 7和7的因子是7 gcd也是7 ?????
//????如何想?
咦咦咦.. 代码断片了...
其实不是忽略了30 30 这种呀,面向数据编程但是没有找到症结所在
症结就是两个因子都有可能!
比如3 30这样,我们知道3,30可以,在30,3也加回来了, 然而5 6 这一对
注意到答案是不一样的,5和18不行,6和15可以,6被人为忽略了
很难发现吧。。 但是其实他们俩是不一样 的
cout << i <<" "<< b << endl;
if (check(i, b, x, y) == true) {
ans++;
if (i != b)ans++;
}
}*/
ll p = y / i;
//cout << "p " << p << endl;
//cout << "i " << i << endl;
if (check(i) == true)ans++;
if (p != i)
{
if (check(p) == true)ans++;
}
}
//为什么呢?因为不要给重复的?...
//test
//else if (y%i != 0);
}
cout << ans << endl;
}
return 0;
}