• BZOJ3512 DZY Loves Math IV


    3512: DZY Loves Math IV

    Time Limit: 15 Sec  Memory Limit: 128 MB

    Description

    给定n,m,求 模10^9+7的值。

    Input

    仅一行,两个整数n,m。

    Output

    仅一行答案。

    Sample Input

    100000 1000000000

    Sample Output

    857275582
    数据规模:
    1<=n<=10^5,1<=m<=10^9,本题共4组数据。

    数论神题系列,成功卡了3天。。。
    首先n很小,直接枚举
    然后根据[ varphi(in) = varphi(i) cdot varphi(frac{n}{d})cdot sum_{emid d} varphi(e) = varphi(i) cdot sum_{emid d}varphi(frac{n}{e}) ]这个式子
    可以推得[ S(n,m) = sum_{dmid n}varphi(frac{n}{d})cdot S(d, lfloor frac{m}{d} floor) ]
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 template <class _T> inline void read(_T &_x) {
      4     int _t; bool flag = false;
      5     while ((_t = getchar()) != '-' && (_t < '0' || _t > '9')) ;
      6     if (_t == '-') _t = getchar(), flag = true; _x = _t - '0';
      7     while ((_t = getchar()) >= '0' && _t <= '9') _x = _x * 10 + _t - '0';
      8     if (flag) _x = -_x;
      9 }
     10 using namespace std;
     11 const int mod = 1e9 + 7;
     12 const int N = 1e5 + 10;
     13 const int M = 7e6 + 10;
     14 typedef long long LL;
     15 inline int add(int a, int b) {
     16     a += b;
     17     if (a < 0) a += mod; if (a >= mod) a -= mod;
     18     return a;
     19 }
     20 inline int mul(int a, int b) {
     21     return (int)((LL)a * b % mod);
     22 }
     23 int phi[M], prime[M / 10], pcnt;
     24 int Div[N], mx[N];
     25 bool vis[M];
     26 inline void init() {
     27     phi[1] = mx[1] = Div[1] = 1;
     28     for (register int i = 2, j, tmp; i < M; ++i) {
     29         if (!vis[i]) {
     30             prime[++pcnt] = i;
     31             phi[i] = i - 1;
     32             if (i < N) Div[i] = 1, mx[i] = i;
     33         }
     34         for (j = 1; j <= pcnt && (LL)prime[j] * i < M; ++j) {
     35             tmp = prime[j] * i;
     36             vis[tmp] = true;
     37             if (tmp < N) mx[tmp] = prime[j];
     38             if (i % prime[j] == 0) {
     39                 phi[tmp] = phi[i] * prime[j];
     40                 if (tmp < N) Div[tmp] = Div[i] * prime[j];
     41                 break;
     42             }
     43             phi[tmp] = phi[i] * (prime[j] - 1);
     44             if (tmp < N) Div[tmp] = Div[i];
     45         }
     46     }
     47     for (register int i = 2; i < M; ++i) phi[i] = add(phi[i], phi[i - 1]);
     48 }
     49 struct Hash_table {
     50     int tot, fir[10000];
     51     struct Edge {
     52         int v, res, nxt;
     53     }e[100000];
     54     Hash_table() {memset(fir, -1, sizeof fir); tot = 0; }
     55     inline void add(int a, int b, int c) {
     56         e[++tot] = (Edge){b, c, fir[a]};
     57         fir[a] = tot;
     58     }
     59     inline int find(int x) {
     60         int w = x >> 20;
     61         for (int u = fir[w]; ~u; u = e[u].nxt)
     62             if (e[u].v == x) return e[u].res;
     63         return -1;
     64     }
     65     inline void insert(int v, int res) {
     66         add(v >> 20, v, res);
     67     }
     68 }mp;
     69 int Phi(int n) {
     70     if (n < M) return phi[n];
     71     int w = mp.find(n); if (~w) return w;
     72     int res = (int)(((LL)n * (n + 1) >> 1) % mod);
     73     for (int i = 2, j; i <= n; i = j + 1) {
     74         j = n / (n / i);
     75         res = add(res, -mul(j - i + 1, Phi(n / i)));
     76     }
     77     mp.insert(n, res); return res;
     78 }
     79 int sum(int n, int m) {
     80     if (!m) return 0;
     81     if (m == 1) return phi[n] - phi[n - 1];
     82     if (n == 1) return Phi(m);
     83     int &k = mx[n];
     84     return add(mul(sum(n / k, m), k - 1), sum(n, m / k));
     85 }
     86 int f[100010];
     87 int main() {
     88     //freopen("3512.in", "r", stdin);
     89     //freopen("3512.out", "w", stdout);
     90     init();
     91     int n, m, ans = 0; read(n), read(m);
     92     memset(f, -1, sizeof f);
     93     for (int i = 1; i <= n; ++i) {
     94         int k = Div[i], t = i / k, ret;
     95         if (~f[t]) ret = mul(k, f[t]);
     96         else ret = mul(k, (f[t] = sum(t, m)));
     97         ans = add(ans, ret);
     98     }
     99     cout << ans << endl;
    100     return 0;
    101 }
    View Code
  • 相关阅读:
    5月编程语言排行榜:动态语言的前世今生
    编程语言范式
    面向函数范式编程(Functional programming)
    bash脚本测试总结
    BASH的保护性编程技巧
    汇编Shellcode的技巧
    FreeBSD上编写x86 Shellcode初学者指南
    CnAms and cndoc
    Linux下shellcode的编写
    How To Configure NetScaler AppFlow for SolarWinds
  • 原文地址:https://www.cnblogs.com/akhpl/p/6857180.html
Copyright © 2020-2023  润新知