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)=1]

然后我们还要知道

欧拉函数定义式:    phi(n) =  ∑ [(i, n)=1]

1…n中与n互质的数的和: ∑ i*[(i, n)=1] = phi(n)*n / 2,n>1,(n==1时 和为1)

所以

      f(n, a, b) = ∑ i*phi(i) - (∑ phi(i)*i/2 + 1/2) = (∑ i*phi(i)  - 1) / 2

现在问题变成 求 i*phi(i) 的前缀和。由于 n 很大,达到 10^9,线性时间是不够的,要用到杜教筛

不懂杜教筛?出门右拐先去这篇博客研究研究。学会了可以先尝试本篇博客后面的模板题:洛谷P4213

预处理 √n 以内的前缀和后,剩下部分利用整除分块求解的时间复杂度为 O(n^(3/4)),预处理前 k = n^(2/3) 时 时间复杂度可以优化到 O(n^(2/3))。详见大佬的博客分析

AC代码:

#include <cstdio>
#include <unordered_map>
using namespace std;
const int mod = 1e9+;
const int MAXN = ; unordered_map<int, long long> Sumiphi;
int prime[MAXN+], cnt;
long long phi[MAXN+];
long long iphi[MAXN+];
bool isprime[MAXN+]; // 线性筛
void getPrime(int n) {
isprime[] = true;
phi[] = ;
for(int i=;i<=n;i++) {
if(!isprime[i])
prime[++cnt] = i, phi[i] = i-; for(int j=;j<=cnt&&prime[j]*i<=n;j++) {
isprime[prime[j]*i] = true;
phi[prime[j]*i] = phi[i]*(prime[j]-);
if(i%prime[j]==) {
phi[prime[j]*i] = phi[i]*(prime[j]);
break;
}
}
}
// 前缀和
for(int i=;i<=n;i++) {
iphi[i] = iphi[i-] + phi[i]*i % mod;
iphi[i] %= mod;
}
} const int _two = (+mod)/;
const int _six = ; // 杜教筛求 ∑i*phi(i)
// S(n) = ∑i^2 - ∑d*S(n/d) = n*(n+1)*(2n+1)/6 - ∑d×S(n/d)
long long iphiSum(int n) {
if(n<=MAXN)
return iphi[n];
if(Sumiphi.count(n))
return Sumiphi[n]; long long sum = ;
for(int i=,j;i<=n;i=j+) {
j = n/(n/i);
sum += iphiSum(n/i)*(j-i+)% mod *(i+j) % mod *_two % mod;
}
Sumiphi[n] = ((1LL*n*(n+)% mod *(*n+)% mod *_six % mod - sum)%mod + mod) % mod;
return Sumiphi[n];
} // 答案:
// ( Sum(i*phi(i)) - 1 ) /2
int main() {
getPrime(MAXN);
int T, n, a, b;
scanf("%d", &T);
while(T--) {
scanf("%d %d %d", &n, &a, &b);
printf("%lld\n", (iphiSum(n)-+mod)%mod * _two % mod);
}
return ;
}

P4213 【模板】杜教筛(Sum)

题意:

给定一个正整数 N (N<=2^31-1),求

AC模板:

#include <cstdio>
#include <unordered_map>
using namespace std;
// 参考自:https://www.cnblogs.com/dreagonm/p/10077979.html const int MAXN = ;
unordered_map<int, long long> Sumphi;
unordered_map<int, long long> Summu;
int prime[MAXN+], cnt;
long long mu[MAXN+], phi[MAXN+];
bool isprime[MAXN+]; // 线性筛
void getPrime(int n) {
isprime[] = true;
mu[] = ;
phi[] = ;
for(int i=;i<=n;i++) {
if(!isprime[i])
prime[++cnt] = i, phi[i] = i-, mu[i] = -; for(int j=;j<=cnt&&prime[j]*i<=n;j++) {
isprime[prime[j]*i] = true;
mu[prime[j]*i] = -mu[i];
phi[prime[j]*i] = phi[i]*(prime[j]-);
if(i%prime[j]==) {
mu[prime[j]*i] = ;
phi[prime[j]*i] = phi[i]*(prime[j]);
break;
}
}
}
// 前缀和
for(int i=;i<=n;i++) {
mu[i] += mu[i-];
phi[i] += phi[i-];
}
} // 杜教筛求 ∑u(i)
// S(n) = 1 - ∑S(n/d)
long long muSum(int n) {
if(n<=MAXN)
return mu[n];
if(Summu.count(n))
return Summu[n]; int sum = ;
for(int i=,j;i<=n;i=j+) {
j = n/(n/i);
sum += (j-i+)*muSum(n/i);
}
Summu[n] = - sum;
return Summu[n];
} // 杜教筛求 ∑phi(i)
// S(n) = ∑ i - ∑S(n/d)
long long phiSum(int n) {
if(n<=MAXN)
return phi[n];
if(Sumphi.count(n))
return Sumphi[n]; long long sum = ;
for(int i=,j;i<=n;i=j+) {
j = n/(n/i);
sum += (j-i+)*phiSum(n/i);
}
Sumphi[n] = 1LL*(n+)*n/ - sum;
return Sumphi[n];
} int main() {
getPrime(MAXN);
int T, n;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
printf("%lld %d\n", phiSum(n), muSum(n));
}
return ;
}

CCPC 2019 网络赛 HDU huntian oy (杜教筛)的更多相关文章

  1. 2019.02.12 bzoj3944: Sum(杜教筛)

    传送门 题意: 思路:直接上杜教筛. 知道怎么推导就很简单了,注意预处理的范围. 然后我因为预处理范围不对被zxyoi教育了(ldx你这个傻×两倍常数活该被卡TLE) 喜闻乐见 代码: #includ ...

  2. CCPC 2019 网络赛 1006 Shuffle Card

    // 签到题,比赛时候写双向链表debug了半天,发现有更好方法,记录一下.   Shuffle Card HDU 6707 题意:   有一 \(n\) 张卡片,编号 \(1~n\) ,给定初始编号 ...

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

    HDU 6703 array   题意:   给定一个数组 \(a_1,a_2, a_3,...a_n\) ,满足 \(1 \le a[i]\le n\) 且 \(a[i]\) 互不相同.   有两种 ...

  4. HDU 5608 function [杜教筛]

    HDU 5608 function 题意:数论函数满足\(N^2-3N+2=\sum_{d|N} f(d)\),求前缀和 裸题-连卷上\(1\)都告诉你了 预处理\(S(n)\)的话反演一下用枚举倍数 ...

  5. luoguP4213 【模板】杜教筛(Sum)杜教筛

    链接 luogu 思路 为了做hdu来学杜教筛. 杜教筛模板题. 卡常数,我加了register居然跑到不到800ms. 太深了. 代码 // luogu-judger-enable-o2 #incl ...

  6. HDU6706 huntian oy(2019年CCPC网络赛+杜教筛)

    目录 题目链接 思路 代码 题目链接 传送门 思路 看到这题还比较懵逼,然后机房大佬板子里面刚好有这个公式\(gcd(a^n-b^n,a^m-b^m)=a^{gcd(n,m)}-b^{gcd(n,m) ...

  7. ccpc 网络赛 hdu 6155

    # ccpc 网络赛 hdu 6155(矩阵乘法 + 线段树) 题意: 给出 01 串,要么询问某个区间内不同的 01 子序列数量,要么把区间翻转. 叉姐的题解: 先考虑怎么算 \(s_1, s_2, ...

  8. 2019年南京网络赛E题K Sum(莫比乌斯反演+杜教筛+欧拉降幂)

    目录 题目链接 思路 代码 题目链接 传送门 思路 首先我们将原式化简: \[ \begin{aligned} &\sum\limits_{l_1=1}^{n}\sum\limits_{l_2 ...

  9. HDU 6706 huntian oy(杜教筛 + 一些定理)题解

    题意: 已知\(f(n,a,b)=\sum_{i=1}^n\sum_{j=1}^igcd(i^a-j^a,i^b-j^b)[gcd(i,j)=1]\mod 1e9+7\),\(n\leq1e9\),且 ...

随机推荐

  1. 5.Struts2框架中的ServletAPI如何获取

    1.完全解耦合的方式 如果使用该种方式,Struts2框架中提供了一个类,ActionContext类,该类中提供一些方法,通过方法获取Servlet的API 一些常用的方法如下 * static A ...

  2. Batch - 重定向符号Redirection >

    总结 Don't use a piping operator, which is what ">" Redirection is. 不要使用管道运算符,即“>”. Di ...

  3. J2SE基础-环境配置

    学习资料:毕向东视频 1.为何配置Path? 使用javac编译文件时,先找path里设置的java路径. 如果不配置Path,在命令提示行中,则只能进入bin目录后,才能执行javac,jar等命令 ...

  4. 【重磅来袭】阿里小程序IDE上线8大功能

    时隔两个月,10月10日阿里小程序IDE上线了uni-app 跨平台研发支持.预览和真机调试交互优化.预检测新增代码扫描等8项功能,进一步完善了阿里小程序IDE的功能池,给大家更好的开发体验和环境. ...

  5. 2018阿里云云数据库RDS核心能力演进

    摘要: 2018年云数据库RDS发展上,不但针对MySQL.SQL Server.PostgreSQL提供了适合个人入门用户的基础版产品,以实惠的价格普惠广大中小用户.更加入最新的MariaDB TX ...

  6. HTML5布局篇

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title> ...

  7. 今天工作整整一个月了,来记录一下(web前端)

    25号,工作整整一个月了,时光飞逝, 这一个月以来,无论是工作上还是生活上,都让我成长了很多,也多了些对人生的思考… 先回顾一下找工作的那段时间吧年前找工作有多辛酸,年后找工作就有多幸运那段日子,我这 ...

  8. 8.RabbitMQ 消息传递Java对象

    通过消息服务器传递Java对象,Java类必须实现序列化接口,可以把Java对象转化为字节数组,从消费者或生产者传递到另外一个JVM中,一定需要两个JVM共享这个类,比如是UserInfo类.   1 ...

  9. LeetCode 1019. Next Greater Node In Linked List (链表中的下一个更大节点)

    题目标签:Linked List, Stack 题目给了我们一个 Linked List,让我们找出对于每一个数字,它的下一个更大的数字. 首先把 Linked List 里的数字 存入 ArrayL ...

  10. Day 10:函数全局变量和局部变量及函数嵌套

    全局变量:在所有函数之外赋值的变量,是全局变量. 局部变量:在函数内的变量是,局部变量 一个函数被调用时,就创建了一个局部作用域.在这个函数内赋值的所有变量,存在于该局部作用域内.该函数返回时,这个局 ...