• BZOJ 4816 数字表格


    数字表格

    【问题描述】

    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


    题解:

     可以用O(nlog2n)的普通筛法预处理出来的

    那么剩下的部分就是逆元和分块了

      1 #include<cmath>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<algorithm>
      7 using namespace std;
      8 const int maxt = 1e3 + 233;
      9 const int maxn = 1e6 + 233;
     10 const int mod = 1e9 + 7;
     11 int T;
     12 int n[maxt], m[maxt];
     13 int f[maxn], g[maxn], inv[maxn];
     14 bool vis[maxn];
     15 int p[maxn], mu[maxn];
     16 int suma[maxn], sumb[maxn];
     17 inline void Scan(int &x)
     18 {
     19     char c;
     20     bool o = false;
     21     while(!isdigit(c = getchar())) o = (c != '-') ? o : true;
     22     x = c - '0';
     23     while(isdigit(c = getchar())) x = x * 10 + c - '0';
     24     if(o) x = -x;
     25 }
     26 inline void Fib(int n)
     27 {
     28     f[0] = 0, f[1] = 1;
     29     for(int i = 2; i <= n; ++i)
     30         f[i] = (f[i - 1] + f[i - 2]) % mod;
     31 }
     32 inline void Mobius(int n)
     33 {
     34     mu[1] = 1;
     35     int num = 0;
     36     for(int i = 2; i <= n; ++i)
     37     {
     38         if(!vis[i])
     39         {
     40             p[++num] = i;
     41             mu[i] = -1;
     42         }
     43         for(int j = 1; j <= num; ++j)
     44         {
     45             int s = i * p[j];
     46             if(i * p[j] > n) break;
     47             vis[s] = true;
     48             if(!(i % p[j]))
     49             {
     50                 mu[s] = 0;
     51                 break;
     52             }
     53             else mu[s] = -mu[i];
     54         }
     55     }
     56 }
     57 inline int Pow(int x, int n)
     58 {
     59     int sum = 1;
     60     while(n)
     61     {
     62         if(n & 1) sum = (long long) sum * x % mod;
     63         x = (long long) x * x % mod;
     64         n >>= 1;
     65     }
     66     return sum;
     67 }
     68 inline void Inv(int n)
     69 {
     70     for(int i = 1; i <= n; ++i)
     71         inv[i] = Pow(f[i], mod - 2);
     72 }
     73 inline void Part(int n)
     74 {
     75     for(int i = 1; i <= n; ++i) g[i] = 1;
     76     for(int i = 2; i <= n; ++i)
     77         for(int j = i; j <= n; j += i)
     78         {
     79             if(mu[j / i] == -1) g[j] = (long long) g[j] * inv[i] % mod;
     80             if(mu[j / i] == 1) g[j] = (long long) g[j] * f[i] % mod;
     81         }
     82 }
     83 inline void Sum(int n)
     84 {
     85     suma[0] = 1;
     86     for(int i = 1; i <= n; ++i) suma[i] = (long long) suma[i - 1] * g[i] % mod;
     87     sumb[n] = Pow(suma[n], mod - 2);
     88     for(int i = n - 1; i >= 1; --i) sumb[i] = (long long) sumb[i + 1] * g[i + 1] % mod;
     89     sumb[0] = 1;
     90 }
     91 inline int Ans(int n, int m)
     92 {
     93     int last;
     94     int ans = 1;
     95     int c = min(n, m);
     96     for(int i = 1; i <= c; i = last + 1)
     97     {
     98         last = min(n / (n / i), m / (m / i));
     99         ans = (long long) ans * Pow((long long) suma[last] * sumb[i - 1] % mod, (long long) (n / i) * (m / i) % (mod - 1)) % mod;
    100     }
    101     return ans;
    102 }
    103 int main()
    104 {
    105     Scan(T);
    106     int maxn = 0;
    107     for(int i = 1; i <= T; ++i)
    108     {
    109         Scan(n[i]), Scan(m[i]);
    110         maxn = max(maxn, max(n[i], m[i]));
    111     }
    112     Fib(maxn);
    113     Mobius(maxn);
    114     Inv(maxn);
    115     Part(maxn);
    116     Sum(maxn);
    117     for(int i = 1; i <= T; ++i) printf("%d
    ", Ans(n[i], m[i]));
    118 }
  • 相关阅读:
    本地代码库关联Github
    常用正则表达式
    IDEA开启并配置services窗口
    数据结构总结
    IDEA导入项目后文件出现时钟的原因及解决方案
    win7硬盘安装过程图解(需要编辑)
    How to Create a Automated Task that Runs at a Set Time in Windows 7
    【转】Code Review(代码复查)
    (收藏)C#开源资源大汇总
    Windows Workflow Foundation:向跟踪服务(TrackingService)传递数据
  • 原文地址:https://www.cnblogs.com/lytccc/p/6895118.html
Copyright © 2020-2023  润新知