zoukankan      html  css  js  c++  java
  • [BZOJ4816][Sdoi2017]数字表格

    [BZOJ4816][Sdoi2017]数字表格

    试题描述

    Doris刚刚学习了fibonacci数列。用f[i]表示数列的第i项,那么
    f[0]=0
    f[1]=1
    f[n]=f[n-1]+f[n-2],n>=2
    Doris用老师的超级计算机生成了一个n×m的表格,第i行第j列的格子中的数是f[gcd(i,j)],其中gcd(i,j)表示i,j的最大公约数。Doris的表格中共有n×m个数,她想知道这些数的乘积是多少。答案对10^9+7取模。

    输入

    有多组测试数据。

    第一个一个数T,表示数据组数。
    接下来T行,每行两个数n,m
    T<=1000,1<=n,m<=10^6

    输出

    输出T行,第i行的数是第i组数据的结果

    输入示例

    3
    2 3
    4 5
    6 7

    输出示例

    1
    6
    960

    数据规模及约定

    见“输入

    题解

    要求这么个东西

    考虑枚举 gcd(i, j)

    于是分块套分块,好像能卡过。。。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 1000010
    #define maxt 2828
    #define MOD 1000000007
    #define LL long long
    
    void gcd(LL a, LL b, LL& x, LL& y) {
    	if(!b){ x = 1; y = 0; return ; }
    	gcd(b, a % b, y, x); y -= a / b * x;
    	return ;
    }
    int inv(LL a) {
    	LL x, y;
    	gcd(a, MOD, x, y);
    	return (x % MOD + MOD) % MOD;
    }
    
    int prime[maxn], cp, mu[maxn], smu[maxn], f[maxn], tf[maxn], invt[maxn];
    bool vis[maxn];
    void init() {
    	mu[1] = 1; smu[1] = 1;
    	for(int i = 2; i < maxn; i++) {
    		if(!vis[i]) prime[++cp] = i, mu[i] = -1;
    		for(int j = 1; i * prime[j] < maxn && j <= cp; j++) {
    			vis[i*prime[j]] = 1;
    			if(i % prime[j] == 0){ mu[i*prime[j]] = 0; break; }
    			mu[i*prime[j]] = -mu[i];
    		}
    		smu[i] = smu[i-1] + mu[i];
    	}
    	int f1 = 0, f2 = 1; tf[1] = invt[1] = 1; invt[0] = 1;
    	for(int i = 2; i < maxn; i++) {
    		swap(f1, f2); f2 += f1; if(f2 >= MOD) f2 -= MOD;
    		tf[i] = (LL)tf[i-1] * f2 % MOD;
    		invt[i] = inv(tf[i]);
    	}
    	return ;
    }
    
    LL get[maxt][maxt];
    LL g(int n, int m) {
    	if(n < maxt && m < maxt) {
    		LL& ans = get[n][m];
    		if(ans) return ans;
    		for(int i = 1, lst; i <= n; i = lst + 1) {
    			lst = min(n / (n / i), m / (m / i));
    			ans += (LL)(n / i) * (m / i) * (smu[lst] - smu[i-1]);
    		}
    		return ans;
    	}
    	LL ans = 0;
    	for(int i = 1, lst; i <= n; i = lst + 1) {
    		lst = min(n / (n / i), m / (m / i));
    		ans += (LL)(n / i) * (m / i) * (smu[lst] - smu[i-1]);
    	}
    	return ans;
    }
    
    int Pow(int a, LL b) {
    	int t = a, ans = 1;
    	while(b) {
    		if(b & 1) ans = (LL)ans * t % MOD;
    		t = (LL)t * t % MOD; b >>= 1;
    	}
    	return ans;
    }
    
    int main() {
    	init();
    	
    	int T = read();
    	while(T--) {
    		int n = read(), m = read(), ans = 1;
    		if(n > m) swap(n, m);
    		for(int i = 1, lst; i <= n; i = lst + 1) {
    			lst = min(n / (n / i), m / (m / i));
    			ans = (LL)ans * Pow((LL)tf[lst] * invt[i-1] % MOD, g(n / i, m / i)) % MOD;
    		}
    		printf("%d
    ", ans);
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    HTML简介
    Tomcat创建项目
    旅游移动端网站—慢!慢!慢!
    云服务正在吞噬世界!
    2016运维团队所需解决方案的5个关键因素
    关于 OneAPM Cloud Test DNS 监控的几个重要问题
    不可忽视的 .NET 应用5大性能问题
    从 IT 中断中学到的最佳监控实践
    衡量企业应用数据库性能的6大指标
    云监控崛起,你落伍了么?
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/7109941.html
Copyright © 2011-2022 走看看