【HDU 5528】Count a * b(推导)

Problem Description
Marry likes to count the number of ways to choose two non-negative integers a and b less than m to make a×ba × bmodm≠0m ≠ 0 .
Let’s denote f(m)f ( m )as the number of ways to choose two non-negative integers a and b less than m to makea×ba × bmodm≠0m ≠ 0 .
She has calculated a lot of f(m) for different m, and now she is interested in another functiong(n)=∑m|nf(m)g ( n ) = ∑ m | n f ( m ) . For example,g(6)=f(1)+f(2)+f(3)+f(6)=0+1+4+21=26g ( 6 ) = f ( 1 ) + f ( 2 ) + f ( 3 ) + f ( 6 ) = 0 + 1 + 4 + 21 = 26 . She needs you to double check the answer.
【HDU 5528】Count a * b(推导)
文章图片

Give younn . Your task is to findg(ng ( n ) modulo2642 64 .
Input
The first line contains an integer T indicating the total number of test cases. Each test case is a line with a positive integer n.
1≤T≤200001 ≤ T ≤ 20000
1≤n≤1091 ≤ n ≤ 10 9
Output
For each test case, print one integer s, representing g(n) modulo 264.
Sample Input
2
6
514
Sample Output
26
328194
Source
2015ACM/ICPC亚洲区长春站-重现赛(感谢东北师大)
先推一下 ff :

f(m)=m2?∑i=1m∑j=1mm|i?j=m2?∑i=1m∑j=1mm(m,i)|i(m,i)?jf ( m ) = m 2 ? ∑ i = 1 m ∑ j = 1 m m | i ? j = m 2 ? ∑ i = 1 m ∑ j = 1 m m ( m , i ) | i ( m , i ) ? j
可以发现 m(m,i)和i(m,i)m ( m , i ) 和 i ( m , i )已经是互质了,所以要整除m, jj必须是 m(m,i)m ( m , i )的倍数,其数量显然是 (m,i)( m , i )个,则: f(m)=m2?∑i=1m(m,i)f ( m ) = m 2 ? ∑ i = 1 m ( m , i )
这里是老套路,去枚举gcd:最终就有: f(m)=m2?∑d|md??(md)f ( m ) = m 2 ? ∑ d | m d ? ? ( m d )
来看 gg ,所以:
g(n)=∑m|nm2?∑m|n∑d|md?(md)g ( n ) = ∑ m | n m 2 ? ∑ m | n ∑ d | m d ? ( m d )
把d拿到最外层: g(n)=∑m|nm2?∑d|nd∑d|m,m|n?(md)=g(n)=∑m|nm2?∑d|nd∑k|nd?(k)=g(n)=∑m|nm2?∑d|nng ( n ) = ∑ m | n m 2 ? ∑ d | n d ∑ d | m , m | n ? ( m d ) = g ( n ) = ∑ m | n m 2 ? ∑ d | n d ∑ k | n d ? ( k ) = g ( n ) = ∑ m | n m 2 ? ∑ d | n n
【【HDU 5528】Count a * b(推导)】到这里就是去枚举n的所以因子了,用唯一分解来做,然后搜索枚举因子即可。
代码:

#include #include #include #include #include #define ullunsigned long long #define ll long long #define ul unsigned int #define maxn 40000 using namespace std; bool isP[maxn]; int prime[maxn]; int cnt; void init() { for(int i=2; i1){fac[k]=x; e[k++]=1; } } ull ans=0; void dfs(int cur,ull temp) { if(cur==k) { ans+=temp*temp; return; } dfs(cur+1,temp); ull now=temp; for(int i=1; i<=e[cur]; i++) { now*=fac[cur]; dfs(cur+1,now); } } ull mod=0; int main() { mod=~mod; init(); int t; cin>>t; int n; while(t--) { scanf("%d",&n); int total=1; getFac(n); ans=0; dfs(0,1); for(int i=0; i

    推荐阅读