bzoj 2693: jzptab 线性筛积性函数

2693: jzptab

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 444  Solved: 174
[Submit][Status][Discuss]

Description

Input

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

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

Output

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

Sample Input

1

4 5

Sample Output

122

HINT
T <= 10000

N, M<=10000000

  重新学习了一下积性函数方式推导莫比乌斯反演系列题目,感觉求sigma(gcd(x,y))、sigma(gcd(x,y)==1)用积性函数的性质推导应该还算是简单,但是求sigma(lcm(x,y))用积性函数就非常恶心了,具体推法详见jzp讲稿:

 传送门:http://wenku.baidu.com/link?url=_glgC9AsqkzOGXSe66vrbLWwf9mr_HZujxaAszME0pCbVtRdcTyhqODy801-tgQdoArjJYYwQGwpQ7E4mdA61OsRYO3qciEfusRQ51JPUCy

  这道题是bzoj 2154《 Crash的数字表格》的多组询问版,如果我没记错的话,那道题我用的是O(n)求sigma(lcm(x,y)),但是jzp讲的神奇的方法可以O(n)预处理,O(sqrt(n))询问。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAXP 10010000
#define MAXN 10010000
#define MOD 100000009
typedef long long qword;
bool pflag[MAXP];
int prime[MAXP],topp=-1;
int phi[MAXP];
int gg[MAXP];
qword gs[MAXP];
int mu[MAXP];
void init()
{
        phi[1]=1;
        gg[1]=1;
        mu[1]=1;
        for (int i=2;i<MAXP;i++)
        {
                if (!pflag[i])
                {
                        prime[++topp]=i;
                        phi[i]=i-1;
                        gg[i]=1-i;
                        mu[i]=-1;
                }
                for (int j=0;j<=topp && i*prime[j]<MAXP;j++)
                {
                        pflag[i*prime[j]]=true;
                        if (i%prime[j]==0)
                        {
                                phi[i*prime[j]]=phi[i]*prime[j];
                                gg[i*prime[j]]=gg[i];
                                mu[i*prime[j]]=0;
                                break;
                        }
                        phi[i*prime[j]]=phi[i]*(prime[j]-1);
                        gg[i*prime[j]]=gg[i]*(1-prime[j]);
                        mu[i*prime[j]]=-mu[i];
                }
        }
        for (int i=1;i<MAXP;i++)
                gs[i]=(gs[i-1]+(qword)gg[i]*i)%MOD;
        return ;
}
qword solve(int n,int m)
{
        qword res=0;
        int l=1;
        for (int i=1;i<=min(n,m);i=l)
        {
                l=min(n/(n/i),m/(m/i))+1;
                res=(res+((qword)(n/i)*(n/i+1)/2%MOD)%MOD*((qword)(m/i)*(m/i+1)/2%MOD)%MOD*(gs[l-1]-gs[i-1])%MOD)%MOD;
        }
        res=(res+MOD)%MOD;
        return res;
}

int main()
{
        freopen("input.txt","r",stdin);
        int n,m;
        int nn;
        init();
        scanf("%d",&nn);
        while (nn--)
        {
                scanf("%d%d",&n,&m);
                printf("%lld\n",solve(n,m));
        }
}
时间: 2024-11-06 14:20:43

bzoj 2693: jzptab 线性筛积性函数的相关文章

bzoj 4407 于神之怒加强版 —— 反演+筛积性函数

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4407 推导如这里:https://www.cnblogs.com/clrs97/p/5191506.html 然后发现 \( F(D) \) 是一个积性函数,可以筛质数的同时筛出来: 首先,单个质数 \( p \) 时只有 \( d=1 \) 和 \( d=p \) 两个因数,所以 \( F[p] = p^{k} - 1 \) 然后如果筛到互质的数,直接把 \( F() \) 相乘即可:

BZOJ 2190 仪仗队(线性筛欧拉函数)

简化题意可知,实际上题目求得是gcd(i,j)=1(i,j<=n)的数对数目. 线性筛出n大小的欧拉表,求和*2+1即可.需要特判1. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # inclu

BZOJ 2693: jzptab [莫比乌斯反演 线性筛]

2693: jzptab Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1194  Solved: 455[Submit][Status][Discuss] Description Input 一个正整数T表示数据组数 接下来T行 每行两个正整数 表示N.M Output T行 每行一个整数 表示第i组数据的结果 Sample Input 1 4 5 Sample Output 122 HINT T <= 10000 N, M<=1000000

线性筛及其扩展-积性函数

线性筛 埃氏筛 对于每个数x,枚举其倍数,将kx筛去. 在埃氏筛过程中,每个数都会被筛掉多次,且对于每个数x,枚举其倍数的次数为\(\frac{n}{x}\) 故埃氏筛的时间复杂度为\(\sum_{i=1}^{n}\)\(\frac{n}{i}\)=n\(\sum_{i=1}^{n}\)\(\frac{1}{i}\)=\(n ln(n)\) 欧拉筛 在埃氏筛中,每个数会被筛掉多次,想要进一步下降复杂度,我们要求每个数只会被筛一次. 要想将多种筛去x的方法固定(唯一).我们就要采用一种方法-"最小

积性函数,线性筛入门 HDU - 2879

HDU - 2879HeHe 题意:He[N]为[0,N−1]范围内有多少个数满足式子x2≡x (mod N),求HeHe[N]=He[1]×……×He[N] 我是通过打表发现的he[x]=2k,k为x是质因子个数,不过这是可以通过积性函数证明的. 关于积性函数的定义: 对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时,f(ab)=f(a)f(b),在数论上就称它为积性函数.若对于某积性函数 f(n) ,就算a, b不互质,也有f(ab)=f(a)f(b),则称它为完全积性

读贾志鹏《线性筛法与积性函数》笔记

1.欧拉筛法在线性时间内求素数以及欧拉函数 代码: 1 procedure get; 2 var i,j,k:longint; 3 begin 4 tot:=0; 5 fillchar(check,sizeof(check),false); 6 for i:=2 to n do 7 begin 8 if not(check[i]) then 9 begin 10 inc(tot); 11 p[tot]:=i; 12 fai[i]:=i-1; 13 end; 14 for j:=1 to tot

常用积性函数的线性筛法整理

简单整理推导加代码,留复习用. 线性筛素数 最简单也最基础,直接看代码就好了\(--\) code: void Euler_Phi_Prime(int n) { is_prime[1] = true; for (int i = 2; i <= n; i++) { if (!is_prime[i]) prime[++cnt] = i; for (int j = 1; j <= cnt && i * prime[j] <= n; j++) { is_prime[i * pri

hdu2421-Deciphering Password-(欧拉筛+唯一分解定理+积性函数+立方求和公式)

Deciphering Password Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2357    Accepted Submission(s): 670 Problem Description Xiaoming has just come up with a new way for encryption, by calculati

积性函数求和:筛法DP、洲阁筛

如果定义在正整数集上的函数 $f(n)$ 满足对于任意一对互素正整数 $n, m$ 都有 $f(n)f(m)=f(nm)$, 那么 $f$ 就叫做积性函数. 积性函数又可以表示为,假设 $n$ 的素因子分解式为 $n=\prod_{i=1}^mp_i^{c_i}$, 那么 $f(n)=\prod_{i=1}^mg(p_i, c_i)$. 本文讨论的函数满足:$g(p, c)$ 能够快速求单点值,且 $g(x, 1)$ 是关于 $x$ 的低次多项式. 积性函数求和,就是要求出 $\sum_{n=1