luogu P1587 [NOI2016] cycle of the United States

Portal

You must first know what kind of number is "pure number of cycles."By meterCan be found in such numbers if and only if the denominator and \ (k \) are relatively prime, because, first of all consider the division process, each time give the remainder of the current \ (* k \) , and then do the division with remainder denominator, once the loop should appear to make a certain addition to the remainder after appear before too. there Euler's theorem and \ (a ^ {\ varphi ( n)} \ equiv 1 (\ mod n) (\ gcd (a, n ) = 1) \) , so it can make the remainder when a decimal point in the calculation reappears after several

Then to such different values, so they are actually required this thing \ [\ sum_ {i = 1 } ^ {n} \ sum_ {j = 1} ^ {m} [\ gcd (i, j) = 1] [\ gcd (j, k) = 1 ] \]

Only the first \ (J \) and \ (K \) ahead \ [\ sum_ {j = 1 } ^ {m} [\ gcd (j, k) = 1] \ sum_ {i = 1} ^ {n } [\ gcd (i, j ) = 1] \]

Then \ ([\ gcd (j, k) = 1] \) conversion click \ [\ sum_ {j = 1 } ^ {m} \ sum_ {d | j, d | k} \ mu (d) \ sum_ {i = 1} ^ {n } [\ gcd (i, j) = 1] \]

\(d\)提前\[\sum_{d=1}^{m}\mu(d)\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor} \sum_{i=1}^{n}[\gcd(i,jd)=1]\]\[\sum_{d=1}^{m}\mu(d)\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor} \sum_{i=1}^{n}[\gcd(i,j)=1][\gcd(i,d)=1]\]

Behind that is a little familiar? If we remember \ (s (i, j, k) = \ sum_ {i = 1} ^ {n} \ sum_ {j = 1} ^ {m} [\ gcd (i, j ) =. 1] [\ GCD (J, K) =. 1] \) , then we can get \ [s (i, j, k) = \ sum_ {d | k} \ mu (d) s (\ lfloor \ frac {m} {d} \ rfloor, n, d) \]

This recursive process like, the boundary is \ (m = 0 \) or \ (n = 0 \) when \ (0 \) , \ (K =. 1 \) when \ (\ sum_ {i = 1 } ^ {n-} \ sum_ {J =. 1} ^ {m} [\ GCD (I, J) =. 1] \) , number Theory block + DU teach sieve can. complexity probably \ (O (\ log n \ log m \} + n-n-sqrt {^ {\ FRAC. 3} {2} {}) \) , this is relatively slow, the increase of the memory have more than 1800 ms

// luogu-judger-enable-o2
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define db double

using namespace std;
const int N=5e6+10,M=2000+10;
int rd()
{
    int x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int n,m,k,prm[N],tt;
bool pp[N];
LL mu[N];
map<int,LL> f;
int lm;
LL siv(int nn)
{
    if(nn<=N-10) return mu[nn];
    if(f.count(nn)) return f[nn];
    LL &an=f[nn];
    an=1;
    for(int i=2,j;i<=nn;i=j+1)
    {
        j=nn/(nn/i);
        an-=1ll*siv(nn/i)*(j-i+1);
    }
    return an;
}
LL ff(int nn,int mm)
{
    lm=min(nn,mm);
    LL an=0;
    for(int i=1,j;i<=lm;i=j+1)
    {
        j=min(nn/(nn/i),mm/(mm/i));
        an+=1ll*(siv(j)-siv(i-1))*(nn/i)*(mm/i);
    }
    return an;
}
vector<int> dd[M];
struct node
{
    int n,m,k;
    bool operator < (const node &bb) const {return n!=bb.n?n<bb.n:(m!=bb.m?m<bb.m:k<bb.k);}
};
map<node,LL> g;
LL sov(int n,int m,int k)
{
    if(n<=0||m<=0) return 0;
    node nw=(node){n,m,k};
    if(g.count(nw)) return g[nw];
    if(k==1) return g[nw]=ff(n,m);
    LL an=0;
    vector<int>::iterator it;
    for(it=dd[k].begin();it!=dd[k].end();++it)
    {
        int i=*it;
        an+=1ll*sov(m/i,n,i)*(mu[i]-mu[i-1]);
    }
    return g[nw]=an;
}

int main()
{
    mu[1]=1;
    for(int i=2;i<=N-10;++i)
    {
        if(!pp[i]) prm[++tt]=i,mu[i]=-1;
        for(int j=1;j<=tt&&i*prm[j]<=N-10;++j)
        {
            pp[i*prm[j]]=1;
            if(i%prm[j]==0) break;
            mu[i*prm[j]]=-mu[i];
        }
    }
    for(int i=2;i<=N-10;++i) mu[i]+=mu[i-1];
    n=rd(),m=rd(),k=rd();
    for(int i=1;i<=k;++i)
        if(k%i==0) dd[k].push_back(i);
    int nn=dd[k].size();
    for(int i=0;i<nn-1;++i)
    {
        int x=dd[k][i];
        vector<int>::iterator it;
        for(it=dd[k].begin();it!=dd[k].end();++it)
        {
            int y=*it;
            if(x<y) break;
            if(x%y==0) dd[x].push_back(y);
        }
    }
    printf("%lld\n",sov(n,m,k));
    return 0;
}

Guess you like

Origin www.cnblogs.com/smyjr/p/11128521.html