Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fstream>
- #include <iostream>
- #include <algorithm>
- #include <iomanip>
- #include <set>
- #include <vector>
- #include <cmath>
- #include <map>
- using namespace std;
- void solve();
- int main()
- {
- ios::sync_with_stdio(0);
- solve();
- }
- #define double long double
- const int MAXN = 1e8;
- const int MAXdiv = sqrt(MAXN);
- vector<int> myprime;
- int p[MAXN];
- void get_prime()
- {
- for (int i = 4; i<=MAXN/2; i+=2)
- p[i] = 1;
- for (int i = 3; i<=MAXN/3; i+=2)
- if (p[i]==0)
- {
- myprime.push_back(i);
- if (i<=1e4)
- for (int j = i*i; j<MAXN; j+=i)
- p[j] = 1;
- }
- }
- const int kol = 7;
- int border[] = {100,1000,10000,100000,1000000,10000000,100000000};
- double graph[kol];
- int cnt[kol];
- int len = MAXN/kol;
- void update(int n, double res)
- {
- // out << fixed << setprecision(15) << n << " "<< res << endl;
- for (int i =0; i<kol; i++)
- {
- if (border[i]>=n)
- {
- cnt[i]++;
- graph[i]+=res;
- break;
- }
- }
- }
- int gcd(int a, int b)
- {
- while (a)
- {
- b%=a;
- swap(a,b);
- }
- return b;
- }
- vector<int> dividers(int div1, int div2)
- {
- int g = gcd(div1,div2);
- vector<int> res;
- for (int i = 1; i*i<=g; i++)
- {
- if (g%i==0)
- {
- res.push_back(i);
- if (g/i!=i)
- res.push_back(g/i);
- }
- }
- return res;
- }
- int phi[MAXdiv];
- void count_phi(int n, int pr, int pk, int pkminus1, int last)
- {
- phi[n] = pr*(pk-pkminus1);
- for (int i = max(0,last); i<myprime.size(); i++)
- {
- int nextphi = n*myprime[i];
- if (nextphi>=MAXdiv)
- return;
- if (i==last)
- {
- int pkm1 = 0;
- if (pkminus1==0)
- pkm1 = 1;
- else
- pkm1 = pkminus1*myprime[i];
- count_phi(nextphi,pr,pk*myprime[i],pkm1,i);
- }
- else
- {
- count_phi(nextphi, phi[n], myprime[i], 1, i);
- }
- }
- }
- int Phi(int n)
- {
- return phi[n];
- }
- const int maxpow = 10;
- vector<vector<int>> getclasses(vector<int> D)
- {
- vector<char>used(D.size());
- vector<vector<int>>bin(maxpow);
- for (int b = maxpow-1; b>=0; b--)
- {
- for (int i = 0; i<D.size(); i++)
- {
- if (used[i])
- continue;
- if ((D[i] & ( (1ll<<b)-1))==0) // это проверка на делимость
- {
- bin[b].push_back(D[i]);
- used[i] = 1;
- }
- }
- }
- return bin;
- }
- int s[maxpow];
- int calc_pq(int p, int q)
- {
- vector<int> D = dividers(p-1, q-1);
- vector<vector<int>> bin = getclasses(D);
- int ans = 0;
- for (int i = 0; i<maxpow; i++)
- {
- s[i] = 0;
- for (int j = 0;j<bin[i].size(); j++)
- s[i]+=Phi(bin[i][j]);
- ans+=s[i]*s[i];
- }
- return ans;
- }
- void gen_pq()
- {
- int sz = myprime.size();
- for (int i = 0; i<sz-1; i++)
- {
- if (myprime[i]*myprime[i+1]>MAXN)
- break;
- // cerr << myprime[i] << endl;
- for (int j = i+1; j<sz; j++)
- {
- if (myprime[i]*myprime[j]>MAXN)
- break;
- int n = myprime[i]*myprime[j];
- int x = calc_pq(myprime[i],myprime[j]);
- int phi = (myprime[i]-1)*(myprime[j]-1);
- update(n,1.0*x/phi);
- }
- }
- }
- int calc_pqr(int p, int q, int r)
- {
- int n = p*q*r;
- vector<int> divP = dividers(p-1, n/p-1);
- vector<int> divQ = dividers(q-1, n/q-1);
- vector<int> divR = dividers(r-1, n/r-1);
- vector<vector<int>> bin1 = getclasses(divP);
- vector<vector<int>> bin2 = getclasses(divQ);
- vector<vector<int>> bin3 = getclasses(divR);
- int ans = 0;
- for (int i = 0; i<maxpow; i++)
- {
- if (bin1[i].size() == 0||
- bin2[i].size() == 0||
- bin3[i].size() == 0)
- continue;
- int s1 = 0,s2 = 0, s3 = 0;
- for (int j = 0; j<bin1[i].size(); j++)
- s1+=Phi(bin1[i][j]);
- for (int j = 0; j<bin2[i].size(); j++)
- s2+=Phi(bin2[i][j]);
- for (int j = 0; j<bin3[i].size(); j++)
- s3+=Phi(bin3[i][j]);
- ans+=s1*s2*s3;
- }
- return ans;
- }
- void gen_pqr()
- {
- int sz = myprime.size();
- for (int i = 0; i<sz-2; i++)
- {
- if (myprime[i]*myprime[i+1]*myprime[i+2]>MAXN)
- break;
- // cerr << myprime[i] << endl;
- for (int j = i+1; j<sz-1; j++)
- {
- if (1ll*myprime[i]*myprime[j]*myprime[j+1]>MAXN)
- break;
- for (int k = j+1; k<sz; k++)
- {
- int n = myprime[i]*myprime[j]*myprime[k];
- if (n>MAXN)
- break;
- int x = calc_pqr(myprime[i],myprime[j],myprime[k]);
- int phi = (myprime[i]-1)*(myprime[j]-1)*(myprime[k]-1);
- update(n,1.0*x/phi);
- }
- }
- }
- }
- void solve()
- {
- double starttime = clock();
- get_prime();
- double endtime = clock();
- cout <<" для генерации простых чисел понадобилось "<< (endtime-starttime)/CLOCKS_PER_SEC << endl;
- starttime = clock();
- count_phi(1, 1, 1, 0, -1);
- endtime = clock();
- cout <<" для подсчета функции эйлера понадобилось "<< (endtime-starttime)/CLOCKS_PER_SEC << endl;
- starttime = clock();
- gen_pq();
- endtime = clock();
- cout << "для подсчета ответа для двоек понадобилось "<< (endtime-starttime)/CLOCKS_PER_SEC << endl;
- starttime = clock();
- gen_pqr();
- endtime = clock();
- cout << " для подсчета троек понадобилось " << (endtime-starttime)/CLOCKS_PER_SEC << endl;
- ofstream cout("result1e8.txt");
- for (int i = 0; i<kol; i++)
- {
- cout <<fixed << setprecision(15)<<graph[i]/cnt[i] << endl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement