HDU6706 CCPC 2019网络赛 huntian oy 推式子+杜教筛

CCPC 2019 网络赛 HDU 6706 huntian oy

标签

  • 奇奇怪怪的数论结论
  • 杜教筛

前言

简明题意

  • 给定n,a,b,求:
    \[\sum_{i=1}^n\sum_{j=1}^igcd(i^a-j^a,i^b-j^b)[gcd(i,j)=1]\%(10^9+7)\]

思路

  • 首先有一个结论:
    \[gcd(i^a-j^a,i^b-j^b)=i^{gcd(a,b)}-j^{gcd(a,b)}\]
  • 上面的结论对于i,j互质是成立的。关注这题,条件式里就有[gcd(i,j)=1],所以我们可以直接替换:(由于ab互质,所以指数直接去掉)
    \[\sum_{i=1}^n\sum_{j=1}^i(i-j)[gcd(i,j)=1]\]
  • (其实我比赛的时候猜出来gcd那一坨就等于i-j,然后我写了个暴力验证一下,发现有些数不相等,当时情急,就没往这方面想了,好难过)
  • 推到这里,就太简单了。接下来我们我们把减法分离开:
    \[\sum_{i=1}^n\sum_{j=1}^ii[gcd(i,j)=1]-\sum_{i=1}^n\sum_{j=1}^ij[gcd(i,j)=1]\]
  • 然后分别求一下这两个式子。第一个式子比较好求,重点是第二个式子。
    \[\sum_{i=1}^n\sum_{j=1}^ij[gcd(i,j)=1]=\frac 12\sum_{i=1}^ni\phi(i)+\frac{[n>=1]}{2}\]

    这个式子的推导过程放在我的博客《数论公式总结》里面了

  • 所以原式就等于
    \[\sum_{i=1}^ni\phi(i)-\frac 12\sum_{i=1}^ni\phi(i)+\frac{[n>=1]}{2}=\frac 12\left(\sum_{i=1}^ni\phi(i)-1\right)\]
  • 好了,n<=1e9,暴力去算和式会超时。这里杜教筛。
  • 令\(f(n)=n\phi(n)\),\(S(n)=\sum\limits_{i=1}^nf(i)\)。我们杜教筛,构造g:
    \[S(n)g(1)=\sum_{i=1}^n(f*g)(i)-\sum_{i=2}^ng(i)S(\frac ni)\]
  • 现在难点就在于怎么找g函数。找g函数,我们一般先把狄利克雷展开:
    \[f*g=\sum_{d|n}d\phi(d)*g(\frac nd)\]
  • 所以很显然了,我们取g=id,卷积就是: \[f*g=\sum_{d|n}n\phi(d)=n\sum_{d|n}\phi(d)\]
  • 而\(\sum\limits_{d|n}\phi(d)=n\)(这个相当于\(\phi*I=id\),用卷积很好证明),所以:
    \[(f*g)(n)=\sum_{d|n}n\phi(d)=n^2\]
  • 所以杜教筛的式子:
    \[S(n)=\sum_{i=1}^ni^2-\sum_{i=2}^niS(\frac ni)\]
  • 然后就能很轻松地杜教筛啦~然而T了...
  • 上面的式子如果需要求积性函数的前缀和,那么大家肯定会写一个线性筛。而这里没有,是不是就代表不需要预处理呢?其实还是需要的,要预处理出\(f(n)=n\phi(n)\)的前缀和,才能降低杜教筛的复杂度。

注意事项

  • 注意溢出问题

总结

  • 杜教筛在分块的那一部分有减法操作,记得那里的减法操作不要写-=,因为那里的减法也要取模...

AC代码

#include<cstdio>
#include<unordered_map>
using namespace std;

const int maxn = 5e6 + 10;
const int mod = 1e9 + 7;

int ksm(int a, int b)
{
    int ans = 1, base = a;
    while (b)
    {
        if (b & 1)
            ans = 1ll * ans * base % mod;
        b >>= 1;
        base = 1ll * base * base % mod;
    }
    return ans;
}

int inv6, inv2;

int prime[maxn], phi[maxn], pre[maxn];
bool no_prime[maxn];
int shai(int n)
{
    int cnt = 0;
    no_prime[1] = phi[1] = 1;

    for (int i = 2; i <= n; i++)
    {
        if (!no_prime[i])
            prime[++cnt] = i, phi[i] = i - 1;

        for (int j = 1; j <= cnt && i * prime[j] <= n; j++)
        {
            no_prime[prime[j] * i] = 1;
            phi[prime[j] * i] = i % prime[j] == 0 ? phi[i] * prime[j] : phi[i] * (prime[j] - 1);
            if (i % prime[j] == 0) break;
        }
    }

    for (int i = 1; i <= n; i++)
        pre[i] = (1ll * pre[i - 1] + 1ll * i * phi[i] % mod) % mod;

    return cnt;
}

unordered_map<int, int> rec;
int S(int n)
{
    if (n <= maxn - 10) return pre[n];
    if (rec[n]) return rec[n];
    long long ans = 1ll * n * (n + 1) % mod * (2 * n + 1) % mod * inv6 % mod;
    int l = 2, r = n;
    while (l <= n)
    {
        r = n / (n / l);
        ans = ((ans - 1ll * (l + r) * (r - l + 1) % mod * inv2 % mod * S(n / l) % mod) % mod + mod) % mod;
        l = r + 1;
    }
    return rec[n] = ans;
}

void solve()
{
    inv6 = ksm(6, mod - 2);
    inv2 = ksm(2, mod - 2);

    shai(maxn - 10);

    int t;
    scanf("%d", &t);
    while (t--)
    {
        int n, a, b;
        scanf("%d%d%d", &n, &a, &b);
        printf("%lld\n", 1ll * (S(n) - 1 + mod) % mod * inv2 % mod);
    }
}

int main()
{
    solve();
    return 0;
}

原文地址:https://www.cnblogs.com/danzh/p/11405721.html

时间: 2024-08-29 03:27:20

HDU6706 CCPC 2019网络赛 huntian oy 推式子+杜教筛的相关文章

CCPC 2019 网络赛 HDU huntian oy (杜教筛)

1005 huntian oy (HDU 6706) 题意: 令,有T次询问,求 f(n, a, b). 其中 T = 10^4,1 <= n,a,b <= 1e9,保证每次 a,b互质. 思路: 首先我们需要知道 公式: gcd(a^n - b^n, a^m - b^m) = a^(gcd(m,n)) - b^(gcd(m,n)) 由a,b互质,原式即为 f(n, a, b) = ∑∑ (i-j)*[(i,j)=1] = ∑ (i*∑ [(i, j)=1] ) - ∑∑ j*[(i, j)=

EOJ Monthly 2019.11 E. 数学题(莫比乌斯反演+杜教筛+拉格朗日插值)

传送门 题意: 统计\(k\)元组个数\((a_1,a_2,\cdots,a_n),1\leq a_i\leq n\)使得\(gcd(a_1,a_2,\cdots,a_k,n)=1\). 定义\(f(n,k)\)为满足要求的\(k\)元组个数,现在要求出\(\sum_{i=1}^n f(i,k),1\leq n\leq 10^9,1\leq k\leq 1000\). 思路: 首先来化简一下式子,题目要求的就是: \[ \begin{aligned} &\sum_{i=1}^n\sum_{j=1

CCPC 2019 网络赛 1002 array (权值线段树)

HDU 6703 ? 题意: ? 给定一个数组 \(a_1,a_2, a_3,...a_n\) ,满足 \(1 \le a[i]\le n\) 且 \(a[i]\) 互不相同. ? 有两种操作:1. 将 \(a[pos]\) 的值加上 100000000:2. 询问不等于任何 \(a[i], (1 \le i \le r)\) 且不小于 \(k\) 的最小值. ? 思路: ? 注意 \(n,k\) 的范围都不超过 100000,对于操作一,相当于删除了这个数(询问的答案一定在区间 \([1, n

CCPC 2017 网络赛

1001.我们的想法是,先构造n个要删掉的点,然后不断给图加边,使得每条边的其中一个点在n个点之中. 我们要使n个点之外的点尽量多,并且每次删掉的点在n个点之外. 贪心的决策是,每次操作,前n个点的度和令外的最大度的点度数相同. 然后删掉这个点之后,之后的操作,剩余的点也满足这个要求.所以度数最大的点必定与n个点有边. 于是可以这样构造,增加n批点(i = 1~n),每次增加n/i个点的,每个增加的点连出i条边到n个点. 这样,n个点每次增加的最大度数不超过1.但每次删点的时候(按n~1批的顺序

2019CCPC网络赛 HD6707——杜教筛

题意 求 $f(n,a,b)=\sum_{i=1}^n \sum_{j=1}^i gcd(i^a-j^a,i^b-j^b)[gcd(i,j)=1]\%(10^9+7)$,$1 \le n,a,b \le 10^9$,共有 $T$ 组测试,其中只有10组的 $n$ 大于 $10^6$. 分析 首先,当 $i, j$互质,$a, b$互质时,有 $gcd(i^a-j^a,i^b-j^b)=i-j$(证明见 链接),也可以打表猜一猜嘛. 可以推出:$$\sum_{d=1}^{N}\mu(d)\cdot

51nod 1220 约数之和(杜教筛 + 推推推推推公式)

题意 给出\(n(1\leq n \leq 10^9)\),求\(\sum_{i=1}^n\sum_{j=1}^n\sigma(ij)\),其中\(\sigma(n)\)表示\(n\)的约数之和. balabala 交了两道杜教筛的的板子题(51nod 1239, 1244)就看到了这题,然后不会搞,然后看题解看了一天一夜终于彻底搞明白一发A掉了...感觉学到了很多,写个博客整理一下,如有错请指出. 技能需求 数论函数与线性筛 莫比乌斯反演(也可以当成容斥去理解) 狄利克雷卷积 杜教筛 强大的数

The Nth Item 南昌网络赛(递推数列,分段打表)

The Nth Item \[ Time Limit: 1000 ms \quad Memory Limit: 262144 kB \] 题意 给出递推式,求解每次 \(F[n]\) 的值,输出所有 \(F[n]\) 的 \(xor\) 值. 思路 对于线性递推数列,可以用特征方程求出他的通项公式,比如这题 \[ F[n] = 3F[n-1]+2F[n-2] \x^2 = 3x+2 \x = \frac{3\pm \sqrt{17}}{2} \] 令 \(F[n] = C_1x_1^n + C_

HDU 6198 2017沈阳网络赛 线形递推

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6198 题意:给出一个数k,问用k个斐波那契数相加,得不到的数最小是几. 解法:先暴力打表看看有没有规律. #include <bits/stdc++.h> using namespace std; int dp[2000][2000]; typedef long long LL; int main() { LL c[50]; c[0]=0; c[1]=1; c[2]=1; for(int i=2;

hdu 6076 huntian oy 杜教筛

打表观察得到,gcd(i,j)==1时,gcd(i^a−j^a,i^b−j^b)的值为i - j.所以,你发现这个题跟ab就没关系了... 变成去求∑∑(i-j)[gcd(i,j) == 1]了.有一个显然的结论,gcd(i,j) == gcd(i-j,i). 设k为i-j,则变成 ∑(i 1->n)∑k(1->i-1)[gcd(i,k) == 1]. 又因为i和i本身,一定不互质,所以变成 ∑(i 1->n)∑k(1->i)[gcd(i,k) == 1].然后有个结论,1…N中与