zoukankan      html  css  js  c++  java
  • Crash的数字表格 BZOJ 2154 / jzptab BZOJ 2693

    jzptab

    【问题描述】

    求:

     

    多组询问

    【输入格式】

    一个正整数T表示数据组数

    接下来T行 每行两个正整数 表示N、M

    【输出格式】

    T行 每行一个整数 表示第i组数据的结果

    【样例输入】

    1
    4 5

    【样例输出】

    122

    【数据范围】

    T <= 10000
    N, M<=10000000


    题解:

    即后面那个部分为 H[T],H[T]是积性函数,求详细证明的话将T和d展开为质因数次幂相乘的形式,考虑线性筛中枚举的质数与被筛数的性质即可

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<iostream>
     6 #include<algorithm>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn = 1e7 + 1;
    10 const int mod = 1e8 + 9;
    11 int cnt;
    12 int h[maxn];
    13 int pri[maxn];
    14 int sum[maxn];
    15 bool vis[maxn];
    16 inline void Scan(int &x)
    17 {
    18     char c;
    19     bool o = false;
    20     while(!isdigit(c = getchar())) o = (c != '-') ? o : true;
    21     x = c - '0';
    22     while(isdigit(c = getchar())) x = x * 10 + c - '0';
    23     if(o) x = -x;
    24 }
    25 inline void Sieve()
    26 {
    27     h[1] = 1;
    28     for(int i = 2; i <= maxn; ++i)
    29     {
    30         if(!vis[i]) pri[++cnt] = i, h[i] = ((-(long long) i * i % mod) + mod + i) % mod;
    31         for(int j = 1; j <= cnt; ++j)
    32         {
    33             int s = pri[j];
    34             long long k = (long long) i * s;
    35             if(k > maxn) break;
    36             vis[k] = true;
    37             if(!(i % s))
    38             {
    39                 h[k] = (long long) s * h[i] % mod;
    40                 break;
    41             }
    42             else h[k] = (long long) h[s] * h[i] % mod;
    43         }
    44     }
    45     for(int i = 1; i <= maxn; ++i) sum[i] = (sum[i - 1] + h[i]) % mod;
    46 }
    47 inline int Sum(int n, int m)
    48 {
    49     return ((long long) n * (n + 1) >> 1) % mod * (((long long) m * (m + 1) >> 1) % mod) % mod;
    50 }
    51 inline int Mobius(int n, int m)
    52 {
    53     int res = 0, last = 0;
    54     if(n > m) swap(n, m);
    55     for(int i = 1; i <= n; i = last + 1)
    56     {
    57         last = min(n / (n / i), m / (m / i));
    58         res = (res + (long long) Sum(n / i, m / i) * ((sum[last] - sum[i - 1] + mod) % mod) % mod) % mod;
    59     }
    60     return res;
    61 }
    62 int main()
    63 {
    64     Sieve();
    65     int n;
    66     Scan(n);
    67     int a, b;
    68     while(n--)
    69     {
    70         Scan(a), Scan(b);
    71         printf("%d
    ", Mobius(a, b));
    72     }
    73 }
  • 相关阅读:
    ZOJ 3332 Strange Country II
    ZOJ 3331 Process the Tasks(双塔DP)
    ZOJ 3326 An Awful Problem(模拟)
    HDU 1796 How many integers can you find(容斥原理)
    HDU 4059 The Boss on Mars(容斥原理)
    HDU 4135 Co-prime(容斥原理)
    HDU 5677 ztr loves substring(回文串加多重背包)
    CodeForces 668B Little Artem and Dance
    CodeForces 667A Pouring Rain
    Java实现 LeetCode 764 最大加号标志(暴力递推)
  • 原文地址:https://www.cnblogs.com/lytccc/p/6663658.html
Copyright © 2011-2022 走看看