2705: [sdoi2012] longge issue time limit: 3 sec memory limit: 128 MB
Submit: 1035 solved: 669
[Submit] [Status] Descriptionlongge has excellent scores in mathematics and is very happy to challenge difficult mathematical problems. Now the question is: given an integer N, you need to find Sigma gcd (I, n) (1 <= I <= N ). Input is an integer (n. Output is an integer. Sample input6
Sample output15
Hint
[Data Scope]
For 60% of the data, 0 <n <= 2 ^ 16.
For 100% of the data, 0 <n <= 2 ^ 32.
Source
Calculate the number of gcd (I, n) = K, that is, the number of gcd (I/k, n/K) = 1, that is, Phi (N/K ).
This topic makes me realize whether I think about it or not. I always think about it first, and there is no way to change my mind. Taking this question as an example, at first glance, I decided that it was the subject of the mobyus inversion and there was no other way to think about it.
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<set>#include<map>#include<vector>#include<string>#include<queue>using namespace std;#ifdef WIN32#define LL "%I64d"#else#define LL "%lld"#endif#define MAXN 1100000#define MAXV MAXN*2#define MAXE MAXV*2#define INF 0x3f3f3f3f#define INFL 0x3f3f3f3f3f3f3f3fLLtypedef long long qword;inline int nextInt(){ char ch; int x=0; bool flag=false; do ch=getchar(),flag=(ch==‘-‘)?true:flag; while(ch<‘0‘||ch>‘9‘); do x=x*10+ch-‘0‘; while (ch=getchar(),ch<=‘9‘ && ch>=‘0‘); return x*(flag?-1:1);}qword n,m;qword prime[MAXN],topp=-1;bool pflag[MAXN];int gcd(int x,int y){ return (x%y==0) ? y : gcd(y,x%y);}void init(){ int i,j; for (i=2;i<MAXN;i++) { if (!pflag[i]) { prime[++topp]=i; } for (j=0;j<=topp && i*prime[j]<MAXN;j++) { pflag[i*prime[j]]=true; if (i%prime[j]==0) { break; } } }}qword phi(qword x){ int i; qword ret=1; for (i=0;i<=topp && prime[i]*prime[i]<=x;i++) { if(x%prime[i]==0) { ret*=prime[i]-1; x/=prime[i]; while (x%prime[i]==0) { ret*=prime[i]; x/=prime[i]; } } } if (x>1) { ret*=x-1; } return ret;}int main(){ freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); qword i; scanf("%d",&n); qword ans1=0,ans2=0; // for (i=1;i<=n;i++) // ans1+=gcd(i,n); // printf("%d\n",ans1); init(); qword l=ceil(sqrt(n)); for (i=1;i*i<n;i++) { if (n%i==0) { ans2+=(qword)i*phi(n/i); ans2+=(qword)(n/i)*phi(i); } } if (l*l==n) { ans2+=(qword)(n/l)*phi(l); } printf(LL"\n",ans2); return 0;}
Bzoj 2705: [sdoi2012] longge issue pull data