Description
Input
一共T+1行
第1行为数据组数T(T<=10)
第2~T+1行每行一个非负整数N,代表一组询问
Output
一共T行,每行两个用空格分隔的数ans1,ans2
Sample Input
612813302333
Sample Output
1 12 022 -258 -3278 -31655470 2
solution
杜教筛模板题无敌卡常题.
先搬出套路式子:
\[ S(n)=\sum_{i=1}^{n}(f*g)(i)-\sum_{i=2}^{n}g(i)S(\lfloor\frac{n}{i}\rfloor) \] 对于\(\mu(n)\),拿一个\(I(n)=1\)和他卷起来,可以得到:\[ S(n)=1-\sum_{i=2}^{n}S(\lfloor\frac{n}{i}\rfloor) \] 对于\(\varphi(n)\),同样拿一个\(I(n)\)卷起来,得到:\[ S(n)=\frac{n*(n+1)}{2}-\sum_{i=2}^{n}S(\lfloor\frac{n}{i}\rfloor) \] 然后飞速的敲完代码,提交,\(TLE\)......可能是我太弱了,所有的卡常技巧都用上了,然而并没有什么用....
然后突然发现一个这样的事情:
对于\(\varphi(n)\),其实可以写成这个样子:
\[ \varphi(n)=\sum_{i=1}^{n}\epsilon(\gcd(i,n)) \] 其中\(\epsilon(n)=[n=1]\).然后苦思冥想无果后闲着无聊对前缀和反演下:
#includeusing namespace std;#define ll long long void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;}void print(int x) { if(x<0) x=-x,putchar('-'); if(!x) return ;print(x/10),putchar(x%10+48);}void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}const int maxn = 3e6+1;int pri[maxn],vis[maxn],n,tot,inv2,inv6,mu[maxn];void sieve() { mu[1]=1; for(int i=2;i Mu;/*ll sum_phi(int n) { if(n