题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6588

题目大意:求\(\sum_{i=1}^{n}gcd(\left \lfloor \sqrt[3]{i} \right \rfloor,i),\ n\leq 10^{21}\)

题解:考虑对\(\left \lfloor \sqrt[3]{i} \right \rfloor\)分块,将式子转换成\(\sum_{i=1}^{\left \lfloor \sqrt[3]{n} \right \rfloor}\sum_{j=i^3}^{(i+1)^3-1}gcd(i,j)\)

   考虑函数\(f(n,m)=\sum_{i=1}^{m}gcd(n,i)\),由于\(gcd(x,y)=gcd(x\ mod\ y,y)\),可以得出$$f(n,m)=\sum_{i=1}^{m}gcd(n,i)=\left \lfloor \frac{m}{n} \right \rfloor\cdot f(n,n)+f(n,m\ mod\ n)$$

   对于\(f(n,n)\)的值,可以通过枚举\(gcd\)的值求和得出\(f(n,n)=\sum_{d|n}^{ } d \cdot\phi(\frac{n}{d})\),线性筛预处理欧拉函数的值即可\(O(nlogn)\)预处理所有\(f(n,n)\)的值

   对于\(f(n,m)\),同样可以得出,\(f(n,m)=\sum_{d|n}^{ } d  \sum_{i| \frac{n}{d},i\leq \left \lfloor \frac{m}{d} \right \rfloor}^{ }\mu(i)\cdot\left \lfloor \frac{m}{id} \right \rfloor=\sum_{d|n}^{ } \phi(d)\cdot \left \lfloor \frac{m}{d} \right \rfloor\)

   又由于\((i+1)^3-1=i^3+3i^2+3i\)是\(i\)的倍数,所以对于每个循环中的\(i\),有$$\sum_{j=i^3}^{(i+1)^3-1}gcd(i,j)=f(i,i^3+3i^2+3i)-f(i,i^3)+gcd(i,i^3)=(3i+3)\cdot f(i,i)+i$$

   因此对于每个询问,最多只需要求一次\(f(n,m)\)就好(即最后的\(i\)),而求一次\(f(n,m)\)的时间复杂度为\(O(\sqrt{n})\),所以每次询问的复杂度是\(O(n+\sqrt{n})\)。又因为有多组询问,可以考虑通过离线处理将总的时间复杂度降为\(O(nlogn+T\sqrt{n})\),这里\(n\)指的是\(10^7\)

   这题的出题人原本是卡了非线性的做法,但是可以通过一定的常数优化使得\(O(nlogn)\)的做法通过

 #include<bits/stdc++.h>
using namespace std;
#define N 10000001
#define MOD 998244353
int n,g[N],phi[N],p[N],cnt,res[],flg[N];
struct rua
{
int id;
__int128 n;
bool operator <(const rua &t)const{return n<t.n;}
}a[];
void read(__int128 &x)
{
static char ch;static bool neg;
for(ch=neg=;ch<'' || ''<ch;neg|=ch=='-',ch=getchar());
for(x=;''<=ch && ch<='';(x*=)+=ch-'',ch=getchar());
x=neg?-x:x;
}
void pretype()
{
phi[]=;
for(int i=;i<N;i++)
{
if(!flg[i])p[++cnt]=i,phi[i]=i-;
for(int j=;j<=cnt && i*p[j]<N;j++)
{
flg[i*p[j]]=;
if(i%p[j]==)
{
phi[i*p[j]]=p[j]*phi[i];
break;
}
phi[i*p[j]]=(p[j]-)*phi[i];
}
}
for(int d=;d*d<N;d++)
for(int n=d*d;n<N;n+=d)
{
g[n]=(g[n]+1ll*d*phi[n/d])%MOD;
if(d*d<n)g[n]=(g[n]+1ll*(n/d)*phi[d])%MOD;
}
}
inline int F(int n,__int128 M)
{
int res=(M/n)*g[n]%MOD;
int m=M%n;
if(m==)return res;
for(int i=;i*i<=n;i++)
{
int j=n/(n/i);
if(n%i==)
{
res=(res+1ll*phi[i]*(m/i))%MOD;
if(i*i<n)res=(res+1ll*phi[n/i]*(m/(n/i)))%MOD;
}
i=j;
}
return res;
}
int main()
{
pretype();
scanf("%d",&n);
for(int i=;i<=n;i++)
read(a[i].n),a[i].id=i;
sort(a+,a+n+);
int ans=,j=;
__int128 i=;
while(i*i*i<=a[n].n)
{
__int128 r=((i+)*i+)*i;
ans=(ans+MOD-(i*i*g[i]%MOD)+i)%MOD;
while(j<=n && a[j].n<r)
{
res[a[j].id]=(ans+F(i,a[j].n%i)+(a[j].n/i)*g[i])%MOD;
j++;
}
ans=(ans+((i+)*i+)*g[i])%MOD;
while(j<=n && a[j].n==r)
res[a[j++].id]=ans;
i++;
}
for(int i=;i<=n;i++)
printf("%d\n",res[i]);
}

最新文章

  1. spring帝国-开篇
  2. IOS笔记之UIKit_UIAlertView、UIActionSheet
  3. sk_buff
  4. 一个好用的PHP验证码类
  5. 如何配置svn服务器(通过VisualServer服务器)
  6. (转载)Mysql使用Describe命令判断字段是否存在
  7. cf701A Cards
  8. kendo ui grid 汉化
  9. 不是技术牛人,如何拿到国内IT巨头的Offer【转】
  10. 关于ios原声嵌入web页面的问题
  11. K:树、二叉树与森林之间的转换及其相关代码实现
  12. springboot(@Service,@Mapper)注解失效导致无法注入service和mapper
  13. SQL语句中 int 溢出 + Asp语句中 Long 溢出
  14. Java SE关键字-static
  15. functional program language
  16. java工具类-日期工具类
  17. android应用推荐
  18. 编程之美 1.1 让cpu占用率曲线听你指挥(多核处理器)
  19. POJ2074 Line of Sight
  20. Shell Script Practice 2 Summary

热门文章

  1. kafka2.10集群搭建(一)
  2. (三)mysql SQL 基本操作
  3. python 入门(基础)
  4. Python之random.seed()用法
  5. Docker学习+遇坑笔记
  6. 《深入理解 Java 虚拟机》学习 -- 类加载机制
  7. Scala学习十四——模式匹配和样例类
  8. 【小知识点】input输入框在安卓以及IOS手机中光标及字体不居中解决方法
  9. ASP.NET如何接收清楚缓存的通知
  10. CHD-5.3.6集群上sqoop安装