题面

Sakuya's task

\[\left(\sum_{i=1}^n\sum_{j=1}^n \varphi(\gcd(i,j))\right)\bmod 10^9+7
\]

数据范围:\(1\le n\le 10^{10}\)。


蒟蒻语

考场爆零真开森。

本来以为要卷 \(1*1\),没想到真要卷 \(1*1\),只不过要一个一个卷……

考场上还以为要洲阁 \(\tt Min\_25\)。


正解

先莫反操作一发:

\[\begin{split}
&\sum_{i=1}^n\sum_{j=1}^n \varphi(\gcd(i,j))\\
=&\sum_{d=1}^n \varphi(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}\epsilon(\gcd(i,j))\\
=&\sum_{d=1}^n\varphi(d)\sum_{k=1}^{\lfloor\frac{n}{d}\rfloor}\mu(k)\lfloor\frac{n}{dk}\rfloor^2\\
=&\sum_{T=1}^n\lfloor\frac{n}{T}\rfloor^2\sum_{d|T}\varphi(d)\mu(\frac{T}{d})\\
\end{split}
\]

整除分块左边,右边杜教。

第一次杜教:\(f_1=\varphi\),\(g_1=1\),\(f_1*g_1=id\)。

第二次杜教:\(f_2=\varphi*\mu\),\(g_2=1\),\(f_2*g_2=\varphi=f_1\)。

求 \(f_2\) 会多次调用 \(f_1\),但是内部调用的函数 \(x\) 集相等,所以可以一起求:

//Dusieve
bool vis[iN+1];
int duphi[iN+1],dupm[iN+1];
int Phi(ll x){return x<=N?phi[x]:duphi[n/x];}
int Pm(ll x){return x<=N?pm[x]:dupm[n/x];}
void Dusieve(ll x){
if(x<=N||vis[n/x]) return;
vis[n/x]=true;
for(ll l=2,r;l<=x;l=r+1){
r=x/(x/l),Dusieve(x/l);
(duphi[n/x]-=(ll)(r-l+1)*Phi(x/l)%mod)%=mod;
(dupm[n/x]-=(ll)(r-l+1)*Pm(x/l)%mod)%=mod;
}
(duphi[n/x]+=(ll)x%mod*(x%mod+1)/2%mod)%=mod;
(dupm[n/x]+=duphi[n/x])%=mod;
(duphi[n/x]+=mod)%=mod,(dupm[n/x]+=mod)%=mod;
}

还有个问题:怎么线性筛 \(\varphi*\mu\)?

其实可以狄利克雷前缀和一下,但是这里有个更妙的方法:

\(\mu\) 与 \(\varphi\) 为积性,\(\varphi*\mu\) 必为积性。

根据 \(\mu\) 函数的性质与找规律可得:

\[(\varphi*\mu)(1)=1\\
(\varphi*\mu)(p)=p-2\\
(\varphi*\mu)(p^2)=p(\varphi*\mu)(p)+(\varphi*\mu)(1)\\
(\varphi*\mu)(p^3)=p(\varphi*\mu)(p^2)\\
\]

然后根据积性函数性质,就可以线性筛了。

时间复杂度 \(\Theta(n^{\frac{2}{3}})\)。


代码

取模坑死蒟蒻,细节会有注释。

#include <bits/stdc++.h>
using namespace std; //Start
typedef long long ll;
typedef double db;
#define mp(a,b) make_pair(a,b)
#define x first
#define y second
#define be(a) a.begin()
#define en(a) a.end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f; //Data
const int mod=1e9+7;
ll n; int ans; //Sieve
const int N=1e7,iN=1e3;
bool np[N+1];
int phi[N+1],pm[N+1],cnt,p[N];
void Sieve(){
np[1]=true,phi[1]=pm[1]=1;
for(int i=2;i<=N;i++){
if(!np[i]) p[cnt++]=i,phi[i]=i-1,pm[i]=i-2;
for(int j=0;j<cnt&&i*p[j]<=N;j++){
np[i*p[j]]=1;
if(i%p[j]==0){
phi[i*p[j]]=(ll)phi[i]*p[j]%mod;
if((i/p[j])%p[j]==0) pm[i*p[j]]=(ll)pm[i]*p[j]%mod;
else pm[i*p[j]]=((ll)pm[i]*p[j]+pm[i/p[j]])%mod;
break;
}
phi[i*p[j]]=(ll)phi[i]*phi[p[j]]%mod;
pm[i*p[j]]=(ll)pm[i]*pm[p[j]]%mod;
}
}
for(int i=2;i<=N;i++)
(phi[i]+=phi[i-1])%=mod,(pm[i]+=pm[i-1])%=mod;
} //Dusieve
bool vis[iN+1];
int duphi[iN+1],dupm[iN+1];
int Phi(ll x){return x<=N?phi[x]:duphi[n/x];}
int Pm(ll x){return x<=N?pm[x]:dupm[n/x];}
void Dusieve(ll x){
if(x<=N||vis[n/x]) return;
vis[n/x]=true;
for(ll l=2,r;l<=x;l=r+1){
r=x/(x/l),Dusieve(x/l);
(duphi[n/x]-=(ll)(r-l+1)*Phi(x/l)%mod)%=mod;
(dupm[n/x]-=(ll)(r-l+1)*Pm(x/l)%mod)%=mod;
}
(duphi[n/x]+=(ll)x%mod*(x%mod+1)/2%mod)%=mod;
(dupm[n/x]+=duphi[n/x])%=mod;
(duphi[n/x]+=mod)%=mod,(dupm[n/x]+=mod)%=mod;
} //Main
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
Sieve(),Dusieve(n);
// cout<<Pm(n)<<'\n';
for(ll l=1,r;l<=n;l=r+1){
r=n/(n/l);
(ans+=(ll)(n/l%mod)*(n/l%mod)%mod*(Pm(r)-Pm(l-1)+mod)%mod)%=mod;
/*
杜教筛是在开始整除分块前开始的,但是为什么这里可以直接Pm调用呢?
蒟蒻的回答:因为杜教筛内部处理了所有n的整除分块的答案。
*/
}
cout<<ans<<'\n';
return 0;
}

祝大家学习愉快!

题解-Sakuya's task的更多相关文章

  1. 3.26-3.31【cf补题+其他】

      计蒜客)翻硬币 //暴力匹配 #include<cstdio> #include<cstring> #define CLR(a, b) memset((a), (b), s ...

  2. HDU-3974 Assign the task题解报告【dfs序+线段树】

    There is a company that has N employees(numbered from 1 to N),every employee in the company has a im ...

  3. 【题解】 CF11D A Simple Task

    [题解] CF11D A Simple Task 传送门 \(n \le 20\) 考虑状态压缩\(dp\). 考虑状态,\(dp(i,j,O)\)表示从\(i\)到\(j\)经过点集\(O\)的路径 ...

  4. Codeforces 959F Mahmoud and Ehab and yet another xor task 线性基 (看题解)

    Mahmoud and Ehab and yet another xor task 存在的元素的方案数都是一样的, 啊, 我好菜啊. 离线之后用线性基取check存不存在,然后计算答案. #inclu ...

  5. [CF11D]A Simple Task 题解

    题解 我们从最简单的思路开始考虑,首先看到题目发现\(n\)非常小,于是很容易想到状态压缩. 我们考虑比较直觉的状态,f[i][j][k]表示以i为起点,当前在j,之前去过的点状态为k的简单环的方案数 ...

  6. [LeetCode]621. Task Scheduler 任务安排 题解

    题目描述 给定一个char数组,代表CPU需要做的任务,包含A-Z,不用考虑顺序,每个任务能在1个单位完成.但是有规定一个非负整数n代表两个相同任务之间需要至少n个时间单位.球最少数量的时间单位完成所 ...

  7. HDU 3974 Assign the task(DFS序)题解

    题意:给出一棵树,改变树的一个节点的值,那么该节点及所有子节点都变为这个值.给出m个询问. 思路:DFS序,将树改为线性结构,用线段树维护.start[ ]记录每个节点的编号,End[ ]为该节点的最 ...

  8. 题解报告:hdu 4907 Task schedule

    Problem Description 有一台机器,并且给你这台机器的工作表,工作表上有n个任务,机器在ti时间执行第i个任务,1秒即可完成1个任务.有m个询问,每个询问有一个数字q,表示如果在q时间 ...

  9. CF 11D A Simple Task 题解

    题面 这道题的数据范围一看就是dfs或状压啦~ 本文以状压的方式来讲解 f[i][j]表示目前的节点是i,已经经历过的节点的状态为j的简单环的个数: 具体的转移方程和细节请看代码: PS:(i& ...

随机推荐

  1. netfilter内核态与用户态 通信 之 sockopt

    用户态与内核态交互通信的方法不止一种,sockopt是比较方便的一个,写法也简单.缺点就是使用 copy_from_user()/copy_to_user()完成内核和用户的通信, 效率其实不高, 多 ...

  2. Ceph如何实现文件系统的横向扩展

    前言 在跟一个朋友聊天的时候,聊到一个技术问题,他们的一个环境上面小文件巨多,是我目前知道的集群里面规模算非常大的了,但是目前有个问题,一方面会进行一倍的硬件的扩容,而文件的数量也在剧烈的增长着,所以 ...

  3. ceph在centos7下一个不容易发现的改变

    在centos6以及以前的osd版本,在启动osd的时候,回去根据ceph.conf的配置文件进行挂载osd,然后进行进程的启动,这个格式是这样的 [osd.0] host = hostname de ...

  4. 配置cobbler步骤

    首先找到下载包的地址 (使用的是centos6) http://download.opensuse.org/repositories/home:/libertas-ict:/cobbler26/Cen ...

  5. Python基础数据类型与for循环

    数据类型:int,bool,str,list, tuple元组,dict字典. 1.数字:12,3,4 在使用print打印数字时,在终端界面中无法判断出打印的是什么类型,当我们需要知道一个值是什么类 ...

  6. 网站实现微信扫码登录 php

    微信开放平台账号一个,必须是商户,不然你也开不了 1.在开放平台创建应用,并设置回调地址(域名即可) 2.生成二维码,前端代码,用户扫码后会给你的回调地址发送code <span id=&quo ...

  7. mybatis中的一些标签使用

    主要有两个配置文件,一个是主配置文件SqlConfig.xml, 还有一个是dao接口实现类相对应的mapper的配置文件 .比如userDao的userDao.xml配置文件. 1.resultTy ...

  8. GraphicsLab 之 Atmospheric Scattering (一)

    作者:i_dovelemon 日期:2020-10-11 主题:Atmospheric Scattering, Volume Scattering, Rayleigh Scattering, Mie ...

  9. MIT-6.006算法导论(2011秋)

    L01 Algorithmic Thinking,Peak Finding 算法定义:高效处理大量数据的程序 在学本课之前最好先学习6.042,本课进阶为6.046 本门课的8个主要章节:算法思想.排 ...

  10. 手撕HashMap

    前言: 平时工作的时候,用的最多的就是ArrayList和HashMap了,今天看了遍HashMap的源码,决定自己手写一遍HashMap. 一.创建MyHashMap接口       我们首先创建一 ...