题目链接: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)\)的做法通过

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define N 10000001
  4. #define MOD 998244353
  5. int n,g[N],phi[N],p[N],cnt,res[],flg[N];
  6. struct rua
  7. {
  8. int id;
  9. __int128 n;
  10. bool operator <(const rua &t)const{return n<t.n;}
  11. }a[];
  12. void read(__int128 &x)
  13. {
  14. static char ch;static bool neg;
  15. for(ch=neg=;ch<'' || ''<ch;neg|=ch=='-',ch=getchar());
  16. for(x=;''<=ch && ch<='';(x*=)+=ch-'',ch=getchar());
  17. x=neg?-x:x;
  18. }
  19. void pretype()
  20. {
  21. phi[]=;
  22. for(int i=;i<N;i++)
  23. {
  24. if(!flg[i])p[++cnt]=i,phi[i]=i-;
  25. for(int j=;j<=cnt && i*p[j]<N;j++)
  26. {
  27. flg[i*p[j]]=;
  28. if(i%p[j]==)
  29. {
  30. phi[i*p[j]]=p[j]*phi[i];
  31. break;
  32. }
  33. phi[i*p[j]]=(p[j]-)*phi[i];
  34. }
  35. }
  36. for(int d=;d*d<N;d++)
  37. for(int n=d*d;n<N;n+=d)
  38. {
  39. g[n]=(g[n]+1ll*d*phi[n/d])%MOD;
  40. if(d*d<n)g[n]=(g[n]+1ll*(n/d)*phi[d])%MOD;
  41. }
  42. }
  43. inline int F(int n,__int128 M)
  44. {
  45. int res=(M/n)*g[n]%MOD;
  46. int m=M%n;
  47. if(m==)return res;
  48. for(int i=;i*i<=n;i++)
  49. {
  50. int j=n/(n/i);
  51. if(n%i==)
  52. {
  53. res=(res+1ll*phi[i]*(m/i))%MOD;
  54. if(i*i<n)res=(res+1ll*phi[n/i]*(m/(n/i)))%MOD;
  55. }
  56. i=j;
  57. }
  58. return res;
  59. }
  60. int main()
  61. {
  62. pretype();
  63. scanf("%d",&n);
  64. for(int i=;i<=n;i++)
  65. read(a[i].n),a[i].id=i;
  66. sort(a+,a+n+);
  67. int ans=,j=;
  68. __int128 i=;
  69. while(i*i*i<=a[n].n)
  70. {
  71. __int128 r=((i+)*i+)*i;
  72. ans=(ans+MOD-(i*i*g[i]%MOD)+i)%MOD;
  73. while(j<=n && a[j].n<r)
  74. {
  75. res[a[j].id]=(ans+F(i,a[j].n%i)+(a[j].n/i)*g[i])%MOD;
  76. j++;
  77. }
  78. ans=(ans+((i+)*i+)*g[i])%MOD;
  79. while(j<=n && a[j].n==r)
  80. res[a[j++].id]=ans;
  81. i++;
  82. }
  83. for(int i=;i<=n;i++)
  84. printf("%d\n",res[i]);
  85. }

[2019HDU多校第一场][HDU 6588][K. Function]的更多相关文章

  1. [2019HDU多校第一场][HDU 6578][A. Blank]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6578 题目大意:长度为\(n\)的数组要求分别填入\(\{0,1,2,3\}\)四个数中的任意一个,有 ...

  2. [2019HDU多校第一场][HDU 6580][C. Milk]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6580 题目大意:\(n\times m\)大小的方格上有\(k\)瓶水,喝完每瓶水都需要一定的时间.初 ...

  3. [2019HDU多校第一场][HDU 6584][G. Meteor]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6584 题目大意:求所有满足\(0<\frac{p}{q}\leq1, gcd(p,q)=1,p\ ...

  4. [2019HDU多校第一场][HDU 6590][M. Code]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6590 题目大意(来自队友):二维平面上有\(n\)个点,每个点要么是黑色要么是白色,问能否找到一条直线 ...

  5. 2019HDU多校第一场1001 BLANK (DP)(HDU6578)

    2019HDU多校第一场1001 BLANK (DP) 题意:构造一个长度为n(n<=10)的序列,其中的值域为{0,1,2,3}存在m个限制条件,表示为 l r x意义为[L,R]区间里最多能 ...

  6. [2019HDU多校第二场][HDU 6591][A. Another Chess Problem]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6591 题目大意:二维坐标系上,所有满足\(5|2x+y\)的点都被设为障碍物,无法通过.现给出一对点, ...

  7. 2019HDU多校第一场 BLANK DP

    题意:有四种数字,现在有若干个限制条件:每个区间中不同的数字种类必须是多少种,问合法的方案数. 思路: 定义 dp[i][j][k][t] 代表填完前 t 个位置后,{0,1,2,3} 这 4 个数字 ...

  8. 2019HDU多校第一场 String 贪心

    题意:给你一个字符串,问是否存在一个长度为m的子序列,子序列中对应字符的数目必须在一个范围内,问是否存在这样的字符串?如果存在,输出字典序最小的那个. 思路:贪心,先构造一个序列自动机,序列自动机指向 ...

  9. 2019HDU多校第一场 6582 Path 【最短路+最大流最小割】

    一.题目 Path 二.分析 首先肯定要求最短路,然后如何确定所有的最短路其实有多种方法. 1 根据最短路,那么最短路上的边肯定是可以满足$dist[from] + e.cost = dist[to] ...

随机推荐

  1. TensorFlow 官方文档 Programmer's Guide 中文翻译 —— 引言

    TensorFlow Programmer's Guide (Introduction) TensorFlow 编程手册 (引言) #(本项目对tensorflow官网上给出的指导手册(TF1.3版本 ...

  2. abstract class 与 interface

    abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstract class和inte ...

  3. 数据结构C++实现-第一章 绪论

    1.1 计算机与算法 1.1.3 起泡排序 void bubbleSort(int a[], int n) { for(bool sorted=false; !sorted; --n) { sorte ...

  4. 前端vue组件传参

    ## 路由传参 """ 转跳: <router-link :to="'/course/'+course.id">{{course.name ...

  5. python — mysql基础知识

    目录 1 . 数据库的介绍 2. mysql 1 . 数据库的介绍 1.为什么要用数据库? 很多功能如果只是通过操作文件来改变数据是非常繁琐的,程序员需要做很多事情 对于多台机器或者多个进程操作用一份 ...

  6. operator模块和functools模块

    operator模块 在函数式编程中,经常需要把算术运算符当作函数使用.例如,不使用 递归计算阶乘.求和可以使用 sum 函数,但是求积则没有这样的函数. 我们可以使用 reduce 函数(5.2.1 ...

  7. Java并发与多线程教程(1)

    Java并发性与多线程介绍 在过去单CPU时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并不是真正意义上的“同一时间点”,而是多个任务 ...

  8. ActiveMQ入门系列二:入门代码实例(点对点模式)

    在上一篇<ActiveMQ入门系列一:认识并安装ActiveMQ(Windows下)>中,大致介绍了ActiveMQ和一些概念,并下载.安装.启动他,还访问了他的控制台页面. 这篇,就用代 ...

  9. Centos7.7安装swoole

    系统版本:centos 7.7(查看系统版本:cat /etc/redhat-release) 执行命令安装swoole: yum update -y && yum remove ph ...

  10. bash shell脚本之获取时间日期

    shell中的时间日期获取 cat test5: #!/bin/bash # using the backtick character testing=`date` echo "The da ...