码迷,mamicode.com
首页 > 其他好文 > 详细

[ACM-ICPC 2018 沈阳网络赛] G. Spare Tire (思维+容斥)

时间:2019-07-11 20:25:33      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:size   flag   一个   alc   推出   namespace   question   cli   find   

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,23an1?an2??+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 n1bi?n and b_ibi?is relatively-prime with the integer mm. And then calculate:

\displaystyle \sum_{i=1}^{p}a_{b_i}i=1p?abi??

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^81n,m108.

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

SOLUTION:
考虑容斥,用所有的和减去不合法的和
也就是减去ai,其中i和m的gcd不为1
考虑对m进行质因子分解
对于m的每一质因子p我们需要减去小标为p的倍数的a
写出来之后发现可以推出来式子o(1)的进行计算,但是俩个质因子p可能
筛掉一个ai多次,加上容斥就行了

CODE:
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll mod = 1e9+7;
 5 const ll inv6 = 166666668;
 6 const ll inv2 = 500000004;
 7 ll a[10005];
 8 ll clac(ll n,ll i){
 9     n /= i;
10     return (n % mod * (n + 1) % mod * (2 * n + 1) % mod * inv6 % mod * i % mod * i % mod + n % mod * (n + 1) % mod * inv2 % mod * i % mod) % mod;
11 }
12 int main(){
13     ll n,m;
14     while(~scanf("%lld%lld",&n,&m)){
15         int cnt = 0;
16         for(int i = 2; i * i <= m; i++){
17             if(m % i == 0){
18                 a[cnt++] = i;
19                 while(m % i == 0)
20                     m /= i;
21             }
22         }
23         if(m != 1)
24             a[cnt++] = m;
25         ll ans = clac(n,1);
26         ll ans2 = 0;
27         for(int i = 1; i < (1 << cnt); i++){
28             int flag = 0;
29             ll tmp = 1;
30             for(int j = 0; j < cnt; j++){
31                 if(i & (1 << j)){
32                     flag++;
33                     tmp = tmp * a[j] % mod;
34                 }
35             }
36             tmp = clac(n,tmp);
37             if(flag & 1) ans2 = (ans2 % mod + tmp % mod) % mod;
38             else ans2 = (ans2 % mod - tmp % mod + mod) % mod;
39         }
40         printf("%lld\n",(ans % mod - ans2 % mod + mod) % mod);
41     }
42     return 0;
43 }

 












[ACM-ICPC 2018 沈阳网络赛] G. Spare Tire (思维+容斥)

标签:size   flag   一个   alc   推出   namespace   question   cli   find   

原文地址:https://www.cnblogs.com/zhangbuang/p/11172086.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!