zoukankan      html  css  js  c++  java
  • bzoj 4816: 洛谷 P3704: [SDOI2017]数字表格

    洛谷很早以前就写过了,今天交到bzoj发现TLE了。

    检查了一下发现自己复杂度是错的。

    题目传送门:洛谷P3704

    题意简述:

    求 (prod_{i=1}^{N}prod_{j=1}^{M}F_{gcd(i,j)}mod mod) ,其中 (F_{i}) 是斐波那契数列的第 (i) 项, (mod=10^9+7) 。

    (T) 组数据。

    题解:

    喜闻乐见的推式子时间。

    不失一般性,假设 (Nle M) 。

    [egin{aligned}&prod_{i=1}^{N}prod_{j=1}^{M}F_{gcd(i,j)} \=&prod_{k=1}^{N}{F_{k}}^{left(sum_{i=1}^{N};sum_{j=1}^{M};left[gcd(i,j)=k ight] ight)}end{aligned}]

    右上角的指数部分是老套路了。

    [egin{align*}&= sum_{i=1}^{N}sum_{j=1}^{M}left[gcd(i,j)=k ight]\&= sum_{i=1}^{leftlfloorfrac{N}{k} ight floor}sum_{j=1}^{leftlfloorfrac{M}{k} ight floor}left[gcd(i,j)=1 ight]\&= sum_{d=1}^{leftlfloorfrac{N}{k} ight floor}mu(d)leftlfloorfrac{N}{kd} ight floorleftlfloorfrac{M}{kd} ight floorend{align*}]

    所以

    [egin{align*} &= prod_{k=1}^{N}{F_{k}}^{left(sum_{d=1}^{leftlfloorfrac{N}{k} ight floor}mu(d)leftlfloorfrac{N}{kd} ight floorleftlfloorfrac{M}{kd} ight floor ight)}\ &= prod_{T=1}^{N}left(prod_{k|T}{F_{k}}^{mu(frac{T}{k})} ight)^{leftlfloorfrac{N}{T} ight floorleftlfloorfrac{M}{T} ight floor} end{align*}]

    令 (f(n)=prod_{d|n}{F_{d}}^{mu(frac{n}{d})}) 。

    [=prod_{T=1}^{N}{f(T)}^{leftlfloorfrac{N}{T} ight floorleftlfloorfrac{M}{T} ight floor}]

    外层数论分块求出。内层的 (f(T)) 直接暴力预处理,每个数直接乘到它的倍数中,复杂度 (Theta(nlog n))。

    注意实现的时候的时间复杂度,我因为实现多了快速幂的一个 (log) 被卡了。

    正确的时间复杂度应该是 (Theta(N(log N+log mod)+Tsqrt{N}log mod)) 。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 
     5 #define mod 1000000007
     6 #define LL long long
     7 
     8 int Pow(int b, LL e) {
     9     if (e < 0) e += mod - 1;
    10     int a = 1;
    11     for (; e; b = (LL)b * b % mod, e >>= 1)
    12         if (e & 1) a = (LL)a * b % mod;
    13     return a;
    14 }
    15 
    16 bool ip[1000005];
    17 int p[80005], pc;
    18 int mu[1000005];
    19 int f[1000005], fr[1000005];
    20 
    21 void init() {
    22     
    23     ip[1] = 1;
    24     mu[1] = 1;
    25     
    26     for (int i = 2; i <= 1000000; ++i) {
    27         if (!ip[i]) {
    28             p[++pc] = i;
    29             mu[i] = -1;
    30         }
    31         for (int j = 1; j <= pc && (LL)p[j] * i <= 1000000; ++j) {
    32             register int k = p[j] * i;
    33             ip[k] = 1;
    34             if (i % p[j]) mu[k] = -mu[i];
    35             else break;
    36         }
    37     }
    38     
    39     for (int i = 1; i <= 1000000; ++i)
    40         f[i] = 1, fr[i] = 1;
    41     
    42     int A = 1, B = 0;
    43     for (int i = 1; i <= 1000000; ++i) {
    44         B = (A + B) % mod;
    45         A = (B - A + mod) % mod;
    46         int G[3] = {Pow(B, -1), 1, B};
    47         for (int j = i, k = 1; j <= 1000000; j += i, ++k) {
    48             f[j] = (LL)f[j] * G[mu[k] + 1] % mod,
    49             fr[j] = (LL)fr[j] * G[1 - mu[k]] % mod;
    50         }
    51     }
    52     
    53     f[0] = fr[0] = 1;
    54     for (int i = 1; i <= 1000000; ++i)
    55         f[i] = (LL)f[i - 1] * f[i] % mod,
    56         fr[i] = (LL)fr[i - 1] * fr[i] % mod;
    57 }
    58 
    59 int main() {
    60     init();
    61     int T;
    62     scanf("%d", &T);
    63     while (T--) {
    64         int N, M;
    65         scanf("%d%d", &N, &M);
    66         if (N > M) swap(N, M);
    67         int A = 1;
    68         for (int i = 1, j; i <= N; i = j + 1) {
    69             j = min(N / (N / i), M / (M / i));
    70             A = (LL)A * Pow((LL)f[j] * fr[i - 1] % mod, (LL)(N / i) * (M / i)) % mod;
    71         }
    72         printf("%d
    ", A);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    HDU3336 Count the string —— KMP next数组
    CodeForces
    51Nod 1627 瞬间移动 —— 组合数学
    51Nod 1158 全是1的最大子矩阵 —— 预处理 + 暴力枚举 or 单调栈
    51Nod 1225 余数之和 —— 分区枚举
    51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP
    51Nod 机器人走方格 V3 —— 卡特兰数、Lucas定理
    51Nod XOR key —— 区间最大异或值 可持久化字典树
    HDU4825 Xor Sum —— Trie树
    51Nod 1515 明辨是非 —— 并查集 + 启发式合并
  • 原文地址:https://www.cnblogs.com/PinkRabbit/p/10011541.html
Copyright © 2011-2022 走看看