沈阳网络赛G-Spare Tire【容斥】
A sequence of integer \lbrace a_n \rbrace{an} can be expressed as:
\displaystyle a_n = \left\{ \begin{array}{lr} 0, & n=0\\ 2, & n=1\\ \frac{3a_{n-1}-a_{n-2}}{2}+n+1, & n>1 \end{array} \right.an=⎩⎨⎧0,2,23an−1−an−2+n+1,n=0n=1n>1
Now there are two integers nn and mm. I'm a pretty girl. I want to find all b_1,b_2,b_3\cdots b_pb1,b2,b3⋯bp that 1\leq b_i \leq n1≤bi≤n and b_ibiis relatively-prime with the integer mm. And then calculate:
\displaystyle \sum_{i=1}^{p}a_{b_i}i=1∑pabi
But I have no time to solve this problem because I am going to date my boyfriend soon. So can you help me?
Input
Input contains multiple test cases ( about 1500015000 ). Each case contains two integers nn and mm. 1\leq n,m \leq 10^81≤n,m≤108.
Output
For each test case, print the answer of my question(after mod 1,000,000,0071,000,000,007).
Hint
In the all integers from 11 to 44, 11 and 33 is relatively-prime with the integer 44. So the answer is a_1+a_3=14a1+a3=14.
样例输入
4 4
样例输出
14
题目来源
题意:
已知一个数列a 和整数n, m
现在想知道1-n中所有与m互质的数 作为下标的a的和
思路:
预先打表处理的话内存不够 推公式能推出a[i] = (i + 1) * i【虽然我好像没有推出来...】
所以Sn也是可以推出来的
某一个数的倍数的a求和也是可以推的 因为是ki 那么提出一个k来 就可以代入公式求了
小于n 与m互质的数没有什么特殊的规律 但应该想到素数筛时的做法 用上容斥
先求出1-n所有的a的和 再减去所有与m不互质的数
用容斥来求不互质的数 是正是负与质因数的个数有关 如果是奇数个质因数之积的话就是加 偶数就是减
用到了乘法逆元的模板
cal()函数注释掉的部分是WA的 改成了题解的方法就AC了
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 #include<stack> 6 #include<queue> 7 #include<map> 8 #include<vector> 9 #include<cmath> 10 #include<cstring> 11 #include<set> 12 //#include<bits/stdc++.h> 13 #define inf 0x7f7f7f7f7f7f7f7f 14 using namespace std; 15 typedef long long LL; 16 17 const int maxn = 1e5 + 5; 18 const LL mod = 1e9 + 7; 19 LL inv6, inv2; 20 LL n, m; 21 22 23 LL p[maxn]; 24 int cnt; 25 void getprime(LL x) 26 { 27 cnt = 0; 28 for (LL i = 2; i * i <= x; i++) { 29 if (x % i == 0) { 30 p[cnt++] = i; 31 } 32 while (x % i == 0) { 33 x /= i; 34 } 35 } 36 if (x > 1) { 37 p[cnt++] = x; 38 } 39 } 40 41 void ex_gcd(int a, LL b, LL &d, LL &x, LL &y) 42 { 43 if(!b){ 44 d = a; 45 x = 1; 46 y = 0; 47 } 48 else{ 49 ex_gcd(b, a % b, d, y, x); 50 y -= x * (a / b); 51 } 52 } 53 54 int mod_inverse(int a, LL m) 55 { 56 LL x, y, d; 57 ex_gcd(a, m, d, x, y); 58 return (m + x % m) % m; 59 } 60 61 LL cal(LL n, LL k) 62 { 63 /*LL ans = n / k * (n / k + 1) % mod; 64 ans = ans * (2 * n / k + 1) % mod; 65 ans = ans * inv6 % mod * k % mod * k % mod; 66 ans = ans + k * (1 + n / k) % mod * n / k % mod * inv2 % mod;*/ 67 n=n/k; 68 return (n%mod*(n+1)%mod*(2*n+1)%mod*inv6%mod*k%mod*k%mod+n%mod*(n+1)%mod*inv2%mod*k%mod)%mod; 69 //return ans; 70 } 71 72 73 int main() 74 { 75 inv6 = mod_inverse(6, mod); 76 inv2 = mod_inverse(2, mod); 77 //cout<<mod_inverse(6, mod)<<endl<<mod_inverse(2, mod)<<endl; 78 while (scanf("%lld%lld", &n, &m) != EOF) { 79 memset(p, 0, sizeof(p)); 80 getprime(m); 81 LL ans = 0; 82 for(int i = 1; i < (1 << cnt); i++){ 83 int flag = 0; 84 LL tmp = 1; 85 for(int j = 0; j < cnt; j++){ 86 if(i & (1 << j)){ 87 flag++; 88 tmp = tmp * p[j] % mod; 89 } 90 91 } 92 tmp = cal(n, tmp) % mod; 93 if(flag % 2){ 94 ans = (ans % mod + tmp % mod) % mod; 95 } 96 else{ 97 ans = (ans % mod - tmp % mod + mod) % mod; 98 } 99 } 100 printf("%lld\n", (cal(n, 1) % mod - ans % mod + mod) % mod); 101 } 102 return 0; 103 }