zoukankan      html  css  js  c++  java
  • 2019杭电多校一 K. Function (数论)

    大意: 给定$n(nle 10^{21})$, 求$sumlimits_{i=1}^n gcd(lfloorsqrt[3]{i} floor,i)mod 998244353$

    首先立方根可以分块, 转化为

    $sumlimits_{i=1}^{lfloorsqrt[3]{n} floor}sumlimits_{j=i^3}^{min(n,(i+1)^3-1)}gcd(i,j)=sumlimits_{i=lfloorsqrt[3]{n} floor^3}^ngcd(r+1,i)+sumlimits_{i=1}^rsumlimits_{j=i^3}^{(i+1)^3-1}gcd(i,j)$

    然后有$sumlimits_{i=1}^n gcd(S,i)=sumlimits_{d|S}lfloorfrac{n}{d} floorvarphi(d)$, 所以可以得到

    $egin{align}sumlimits_{i=1}^rsumlimits_{j=i^3}^{(i+1)^3-1}gcd(i,j) &=sumlimits_{i=1}^rsumlimits_{d|i}(lfloorfrac{(i+1)^3-1}{d} floor-lfloorfrac{i^3-1}{d} floor)varphi(d) otag \ &= sumlimits_{d=1}^rsumlimits_{i=1}^{lfloorfrac{r}{d} floor}(lfloorfrac{(di+1)^3-1}{d} floor-lfloorfrac{(di)^3-1}{d} floor) otag \ &= sumlimits_{d=1}^rvarphi(d)sumlimits_{i=1}^{lfloorfrac{r}{d} floor}(3di^2+3i+1) otagend{align}$

    可以$O(sqrt[3]{n})$求出.

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    using namespace std;
    typedef long long ll;
    typedef __int128 i128;
    template <class T>
    void read(T &x) {
    	static char ch;static bool neg;
    	for(ch=neg=0;ch<'0' || '9'<ch;neg|=ch=='-',ch=getchar());
    	for(x=0;'0'<=ch && ch<='9';(x*=10)+=ch-'0',ch=getchar());
    	x=neg?-x:x;
    }
    const int P = 998244353, N = 1e7+10;
    int phi[N], p[N], cnt, vis[N];
    void init() {
        phi[1] = 1;
        for (int i=2; i<N; ++i) {
            if (!vis[i]) p[++cnt]=i,phi[i]=i-1;
            for (int j=1,t; j<=cnt&&i*p[j]<N; ++j) {
                vis[t=i*p[j]] = 1;
                if (i%p[j]==0) {phi[t]=phi[i]*p[j];break;}
                phi[t]=phi[i]*phi[p[j]];
            }
        }
    }
    int gcd(int x, int y) {return y?gcd(y,x%y):x;}
    int S_0(int x) {return x;}
    int S_1(int x) {return (ll)x*(x+1)/2%P;}
    int S_2(int x) {return (ll)x*(x+1)%(6ll*P)*(2*x+1)/6%P;}
    int calc(int s, i128 l, i128 r) {
    	int ans = 0, mx = sqrt(s+0.5);
    	--l;
    	REP(d,1,mx) if (s%d==0) {
    		ans = (ans+(r/d-l/d)*phi[d])%P;
    		int t = s/d;
    		if (t!=d) ans = (ans+(r/t-l/t)*phi[t])%P;
    	}
    	return ans;
    }
    
    int main() {
    	init();
    	int t;
    	scanf("%d", &t);
    	while (t--) {
    		i128 n;
    		read(n);
    		int r = 0;
    		while ((i128)(r+2)*(r+2)*(r+2)-1<=n) ++r;
    		int ans = calc(r+1,(i128)(r+1)*(r+1)*(r+1),n);
    		REP(d,1,r) { 
    			int ret = (S_0(r/d)+3ll*S_1(r/d)+3ll*d*S_2(r/d))%P;
    			ans = (ans+(ll)ret*phi[d])%P;
    		}
    		if (ans<0) ans += P;
    		printf("%d
    ", ans);
    	}
    }
    
  • 相关阅读:
    最短路径算法 2.Dijkstra算法
    最短路径算法 1.Floyed-Warshall算法
    POLYGON(动态规划)
    JAG Asia 2016-Similarity of Subtrees(BFS+哈希)
    2019ACM-ICPC南京网络赛Holy Grail (SPFA / Floyd 模板题)
    2019ACM-ICPC南京网络赛Greedy Sequence
    快速输入输出
    2019HDU多校训练第七场J-Just Repeat
    JAG Asia 2017 C-----Prime-Factor Prime(素数区间筛)
    2019HDU多校训练第五场1007-permutation 2
  • 原文地址:https://www.cnblogs.com/uid001/p/11247626.html
Copyright © 2011-2022 走看看