2021-08-20P3327 [SDOI2015]约数个数和
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-08-20P3327 [SDOI2015]约数个数和相关的知识,希望对你有一定的参考价值。
题意:
设 d(x) 为 x 的约数个数,给定 n,m,求
∑
i
=
1
n
∑
j
=
1
m
d
(
i
,
j
)
\\sum_{i=1}^{n}\\sum_{j=1}^{m}d(i,j)
∑i=1n∑j=1md(i,j)
题解:
代码:
// Problem: P3327 [SDOI2015]约数个数和
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3327
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// By Jozky
#include <bits/stdc++.h>
#include <unordered_map>
#define debug( a, b ) printf( "%s = %d\\n", a, b );
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair< int, int > PII;
clock_t startTime, endTime;
// Fe~Jozky
const ll INF_ll = 1e18;
const int INF_int = 0x3f3f3f3f;
void read(){};
template < typename _Tp, typename... _Tps > void read( _Tp& x, _Tps&... Ar )
{
x = 0;
char c = getchar();
bool flag = 0;
while ( c < '0' || c > '9' )
flag |= ( c == '-' ), c = getchar();
while ( c >= '0' && c <= '9' )
x = ( x << 3 ) + ( x << 1 ) + ( c ^ 48 ), c = getchar();
if ( flag )
x = -x;
read( Ar... );
}
template < typename T > inline void write( T x )
{
if ( x < 0 )
{
x = ~( x - 1 );
putchar( '-' );
}
if ( x > 9 )
write( x / 10 );
putchar( x % 10 + '0' );
}
void rd_test()
{
#ifdef LOCAL
startTime = clock();
freopen( "in.txt", "r", stdin );
#endif
}
void Time_test()
{
#ifdef LOCAL
endTime = clock();
printf( "\\nRun Time:%lfs\\n", ( double )( endTime - startTime ) / CLOCKS_PER_SEC );
#endif
}
const int N = 5e4 + 5;
int tot, mu[ N ], p[ N ];
long long s[ N ];
bool vis[ N ];
void init()
{
mu[ 1 ] = 1;
for ( int i = 2; i <= 5e4; ++i )
{
if ( !vis[ i ] )
p[ ++tot ] = i, mu[ i ] = -1;
for ( int j = 1; j <= tot && i * p[ j ] <= 5e4; ++j )
{
vis[ i * p[ j ] ] = 1;
if ( i % p[ j ] == 0 )
{
mu[ i * p[ j ] ] = 0;
break;
}
else
{
mu[ i * p[ j ] ] = -mu[ i ];
}
}
}
for ( int i = 1; i <= 5e4; ++i )
mu[ i ] += mu[ i - 1 ];
for ( int x = 1; x <= 5e4; ++x )
{
long long res = 0;
for ( int i = 1, j; i <= x; i = j + 1 )
j = x / ( x / i ), res += 1LL * ( j - i + 1 ) * ( x / i );
s[ x ] = res;
}
}
int main()
{
init();
int T;
for ( scanf( "%d", &T ); T--; )
{
int n, m;
scanf( "%d%d", &n, &m );
if ( n > m )
swap( n, m );
long long ans = 0;
for ( int i = 1, j; i <= n; i = j + 1 )
{
j = min( n / ( n / i ), m / ( m / i ) );
ans += 1LL * ( mu[ j ] - mu[ i - 1 ] ) * s[ n / i ] * s[ m / i ];
}
printf( "%lld\\n", ans );
}
return 0;
}
以上是关于2021-08-20P3327 [SDOI2015]约数个数和的主要内容,如果未能解决你的问题,请参考以下文章
luogu P3327 [SDOI2015]约数个数和 莫比乌斯反演