[2019HDU first multi-school] [HDU 6588] [K. Function]

Topic links: http://acm.hdu.edu.cn/showproblem.php?pid=6588

Title effect: seeking \ (\ sum_ {i = 1} ^ {n} gcd (\ left \ lfloor \ sqrt [3] {i} \ right \ rfloor, i), \ n \ leq 10 ^ {21} \)

Solution: consider \ (\ left \ lfloor \ sqrt [3] {i} \ right \ rfloor \) block, converting the equation into \ (\ sum_ {i = 1} ^ {\ left \ lfloor \ sqrt [ 3] {n} \ right \ rfloor} \ sum_ {j = i ^ 3} ^ {(i + 1) ^ 3-1} gcd (i, j) \)

   Consider the function \ (f (n, m) = \ sum_ {i = 1} ^ {m} gcd (n, i) \), since \ (gcd (x, y) = gcd (x \ mod \ y, y ) \), can be derived $$ 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) $$

   For values ​​\ (f (n, n) \) may be enumerated by the value of \ (GCD \) derived sum \ (f (n, n) = \ sum_ {d | n} ^ {} d \ cdot \ phi (\ frac {n} {d}) \), the value of the Euler function can be a linear pre-screening \ (O (nlogn) \) all pre \ (f (n, n) \) values

   对于\(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\)

   Also, because \ ((i + 1) ^ 3-1 = i ^ 3 + 3i ^ 2 + 3i \) is (I \) multiple \, so for each cycle \ (I \), there $$ \ 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 $$

   Thus for each interrogation, at most required only once \ (f (n, m) \) like (i.e., the last \ (I \)), for the sake of a \ (f (n, m) \) time complexity degree \ (O (\ sqrt {n}) \), so that each query complexity is \ (O (n + \ sqrt {n}) \). And because a plurality of sets interrogation, offline processing may be considered by the reduced overall time complexity \ (O (nlogn + T \ sqrt {n}) \), where \ (n-\) refers to the \ (10 ​​^ 7 \)

   The topic of people this question was originally card nonlinear approach, but by a certain constant optimization allows \ (O (nlogn) \) practices through

 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[15],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[15];
12 void read(__int128 &x)
13 {
14     static char ch;static bool neg;
15     for(ch=neg=0;ch<'0' || '9'<ch;neg|=ch=='-',ch=getchar());
16     for(x=0;'0'<=ch && ch<='9';(x*=10)+=ch-'0',ch=getchar());
17     x=neg?-x:x;
18 }
19 void pretype()
20 {
21     phi[1]=1;
22     for(int i=2;i<N;i++)
23       {
24       if(!flg[i])p[++cnt]=i,phi[i]=i-1;
25       for(int j=1;j<=cnt && i*p[j]<N;j++)
26         {
27         flg[i*p[j]]=1;
28         if(i%p[j]==0)
29           {
30           phi[i*p[j]]=p[j]*phi[i];
31           break;
32           }
33         phi[i*p[j]]=(p[j]-1)*phi[i];
34         }
35       }
36     for(int d=1;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==0)return res;
48     for(int i=1;i*i<=n;i++)
49       {
50       int j=n/(n/i);
51       if(n%i==0)
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=1;i<=n;i++)
65       read(a[i].n),a[i].id=i;
66     sort(a+1,a+n+1);
67     int ans=0,j=1;
68     __int128 i=1;
69     while(i*i*i<=a[n].n)
70       {
71       __int128 r=((i+3)*i+3)*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+3)*i+3)*g[i])%MOD;
79       while(j<=n && a[j].n==r)
80         res[a[j++].id]=ans;
81       i++;
82       }
83     for(int i=1;i<=n;i++)
84       printf("%d\n",res[i]);
85 }
View Code

 

Guess you like

Origin www.cnblogs.com/DeaphetS/p/11228116.html