zoukankan      html  css  js  c++  java
  • 「SDOI2017」数字表格

    题目链接


    问题分析

    [egin{aligned} Ans&=prod_{i=1}^nprod_{j=1}^mf[gcd(i,j)]\ &=prod_{t=1}^nf(t)^{sumlimits_{i=1}^nsumlimits_{j=1}^m[gcd(i,j)=t]}\ &=prod_{t=1}^nf(t)^{sumlimits_{t|d}^nmu(frac{d}{t})lfloorfrac{n}{d} floorlfloorfrac{m}{d} floor}\ &=prod_{t=1}^nprod_{t|d}f(t)^{mu(frac{d}{t})lfloorfrac{n}{d} floorlfloorfrac{m}{d} floor}\ &=prod_{d=1}^nprod_{t|d}f(t)^{mu(frac{d}{t})lfloorfrac{n}{d} floorlfloorfrac{m}{d} floor}\ &=prod_{d=1}^{n}[prod_{t|d}f(t)^{mu(frac{d}{t})}]^{lfloorfrac{n}{d} floorlfloorfrac{m}{d} floor} end{aligned} ]

    其中对(sumlimits_{i=1}^nsumlimits_{j=1}^m[gcd(i,j)=t])进行莫比乌斯反演。

    (f(t)=sumlimits_{i=1}^nsumlimits_{j=1}^m[gcd(i,j)=t])。设(F(t)=sumlimits_{i=1}^nsumlimits_{j=1}^m[t|gcd(i,j)]=lfloorfrac{n}{t} floorlfloorfrac{m}{t} floor)

    因为(F(t)=sumlimits_{t|d}f(d)),所以(f(t)=sumlimits_{t|d}mu(frac{d}{t})F(d)=sumlimits_{t|d}mu(frac{d}{t})lfloorfrac{n}{d} floorlfloorfrac{m}{d} floor)

    最后的式子中,中括号内的东西可以(O(nlog n))预处理。然后对于每个询问进行整除分块。如果不考虑快速幂,时间复杂度就是(O(Tsqrt n+nlog n))

    参考代码

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    
    const LL Maxn = 1000010;
    const LL N = 1000000;
    const LL Mod = 1000000007;
    LL Num, Prime[ Maxn ], Vis[ Maxn ], Mu[ Maxn ], F[ Maxn ], G[ Maxn ];
    
    LL Power( LL x, LL y ) {
    	if( y == 0 ) return 1LL;
    	LL t = Power( x, y >> 1 );
    	t = t * t % Mod;
    	if( y & 1 ) t = t * x % Mod;
    	return t;
    }
    
    void Init() {
    	F[ 0 ] = 0; F[ 1 ] = 1;
    	for( int i = 2; i <= N; ++i )
    		F[ i ] = ( F[ i - 1 ] + F[ i - 2 ] ) % Mod;
    	Mu[ 1 ] = 1;
    	for( int i = 2; i <= N; ++i ) {
    		if( !Vis[ i ] ) {
    			Mu[ i ] = -1;
    			Prime[ ++Num ] = i;
    		}
    		for( int j = 1; j <= Num && i * Prime[ j ] <= N; ++j ) {
    			Vis[ i * Prime[ j ] ] = 1;
    			if( i % Prime[ j ] ) break;
    			Mu[ i *Prime[ j ] ] = -Mu[ i ];
    		}
    	}
    	for( int i = 0; i <= N; ++i ) G[ i ] = 1;
    	for( int i = 1; i <= N; ++i ) {
    		for( int j = i; j <= N; j += i ) {
    			if( Mu[ j / i ] == 1 ) 
    				G[ j ] = G[ j ] * F[ i ] % Mod;
    			if( Mu[ j / i ] == -1 )
    				G[ j ] = G[ j ] * Power( F[ i ], Mod - 2 ) % Mod;
    		}
    	}
    	for( int i = 1; i <= N; ++i ) G[ i ] = G[ i ] * G[ i - 1 ] % Mod;
    	return;
    }
    
    void Work() {
    	LL n, m;
    	LL Ans = 1;
    	scanf( "%lld%lld", &n, &m );
    	if( n > m ) swap( n, m );
    	for( int i = 1, j; i <= n; i = j + 1 ) {
    		j = min( ( n / ( n / i ) ), ( m / ( m / i ) ) );
    		Ans = Ans * Power( G[ j ] * Power( G[ i - 1 ], Mod - 2 ) % Mod, ( n / i ) * ( m / i ) % Mod ) % Mod;
    	}
    	printf( "%lld
    ", Ans );
    	return;
    }
    
    int main() {
    	Init();
    	int TestCases;
    	scanf( "%d", &TestCases );
    	for( ; TestCases--; ) Work();
    	return 0;
    }
    
  • 相关阅读:
    关于 OpenSmtp 邮件标题过长后出现乱码问题的解决
    用于解析 sohu 新闻页面的 XSLT 文件
    CEGUI 0.7x实现下划线描边图文混排等效果
    Hash算法说明
    D3DXMatrixShadow 函数
    DLL动态链接库和LIB静态链接库之程序员经验分析
    printf格式控制符的完整格式(转载)
    深入说明HDR技术
    Irrlicht不定期分析
    8.3实例程序:平面阴影
  • 原文地址:https://www.cnblogs.com/chy-2003/p/10559345.html
Copyright © 2011-2022 走看看