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. SQLServer2008上的SDE备份和还原

    一.备份 右键数据库>任务>备份.选择完整模式,导出为xxx.bak文件即可. 二.还原 1.创建sde用户名,新建同名数据库xxx,并指定sde为xxx的拥有者. 2.在master上创 ...

  2. JAVA去除抖音视频的水印源码!!!

    @PostMapping("geturl") public DataResponse decodeDouiyin(@RequestBody DouyinRequest req ) ...

  3. Redis探索之路(六):Redis的常用命令

    一:键值相关命令 1.keys Pattern模糊查询 keys my* 2.exists某个key是否存在 exists key1 3.del 删除一个key del key1 4.expire设置 ...

  4. Ruby 中文编码

    Ruby 中文编码 前面章节中我们已经学会了如何用 Ruby 输出 "Hello, World!",英文没有问题,但是如果你输出中文字符"你好,世界"就有可能会 ...

  5. bzoj1059题解

    [解题思路] 因为只要验证可行性,所以考虑行和考虑列是等价的,故我们只考虑行的交换操作. 这样,拆一波点,把每一行拆成两个点,左边为原交换行,右边为目标交换行,原问题等价于能否对这个二分图进行完全匹配 ...

  6. linux centos 安装配置varnish

    安装2.0+版本 前期准备: 下载pcre http://sourceforge.net/projects/pcre/files/pcre/ http://optimate.dl.sourceforg ...

  7. fedora 18~20 中Qt 5.2.1 解决连接mysql数据库出现QMYSQL driver not loaded的问题

    QT       += sql //在.pro文件里加入这一句 //包含头文件 #include <QDebug> #include <QSqlQuery> #include  ...

  8. Spring Boot 遇到空指针

    @Autowired private IRoadRescueService roadRescueService; 千万不要把注入的service类设为static

  9. 数据结构C++版-图

    一.概念及分类 二.图的存储结构 1.邻接矩阵 顶点: 弧: 边: 表达式语句: 2.邻接表 逆邻接表: 3.十字链表 4.邻接多重表 三.图的权值概念及遍历 权值: 图的遍历: 1.深度优先搜索 2 ...

  10. 解决方案-CRM:Vtiger CRM

    ylbtech-解决方案-CRM:Vtiger CRM vtiger CRM是一套基于Web以销售能力自动化(SFA)为主的客户关系管理系统(CRM).它基于是SugarCRM专业版(SPL1.1.2 ...