パーカッション、

トピックリンク:luogu1587

最初は「純粋な小数」のタイトルは非常に奇妙な明確な感じです

画分のための\(\ FRAC {X}、{Y} \) ことを最初にすべての条件を満足する\(GCD(X、Y)= 1 \)が純粋なサイクルは、ループ区間の長さでなければならず、第二にので\(L \ )ように右側に小数点\(Lの\)ビットの小数部は、このように書かれている同じ2つの数字の後に
\ [\ FRAC {X} { Y} - \ lfloor \ FRAC {X} {Y} \ rfloor = \ FRAC {XK ^ L}、{ Y} - \ lfloor FRAC {XK ^ L}、{Y} \ \ rfloor \]

分母使用可能に辺
\ [XY \ lfloor \ FRAC {
X} {Y} \ rfloor = XK ^ LYの\ lfloorの\のFRAC {XK ^ L}、{Y} \ rfloor \] 転置
\ [XK ^ LX = Y( \ lfloorの\のFRAC {XK ^ L
}、{Y} \ rfloor- \ lfloor \ FRAC {X} {Y} \ rfloor)\] その結果、最終的な\(XK ^ Lの\当量のX(MOD \ Y)\) 以来\(GCD(X、Y)= 1 \)で除算しながら両側よう\(X \)与える\を(K ^ Lの\の当量。1(MOD \ Y)\) 存在することは明らかである\(GCD(K、Y )= 1 \)
最後被写体探索がされるように
\ [\ sum_ {i = 1 } ^ n個の\ sum_ {J = 1} ^ M [GCD(I、J)= 1] [GCD(J、K)= 1 ] \]
の両方を処理するための同時反転、その後、明らかに困難な場合は、その最初の考慮
\ [\開始{整列}& \のsum_ {i = 1} ^ n個の\ sum_ {J = 1} ^ M [GCD(I、J)= 1] [GCD(J、K)= 1] \\ =& \ sum_ {i = 1} ^ n個の\ sum_ {J = 1} ^ M [GCD(I、J)= 1] \ sum_ {D | GCD(J、K)}ミュー(D)\ \\ =&\ sum_ | MU \ {D K} (D)\ sum_ {i = 1} ^ n個の\ sum_ {J = 1} ^ {\ lfloorの\のFRAC {M} {D} \ rfloor} [GCD(I、JD)= 1] \\ =&\のsum_ { D | K}ミュー(D)\ sum_ {i = 1} ^ n個の\ sum_ {J = 1} ^ \ {\ lfloorの\のFRAC {M} {D} \ rfloor} [ GCD(I、J)= 1
] [GCD(I、D)= 1] \端{整列} \] これはそれが何ですか?方程式の形式二つの長手方向ほぼ均一に注目し、言及されてもよい(F(N、M、\ K)= \ sum_ {i = 1} ^ n個の\ sum_ {jは= 1} ^ M [GCD(i、j)を= 1] [GCD(J、K)= 1] \)。。 その後\(F(N、M、 K)= \ sum_ {D | K} \ MU(D)F(\ lfloorの\のFRAC {M} { D} \ rfloor、N、D
)\) 境界条件、最初の場合\(F(0、M、
K)は、F(nは、0、K)= = 0 \) 次に\(F(N、M、 1) = \ sum_。1} ^ {N-I = \ sum_ 1} = {J ^ M [GCD(I、J)= 1] \) これだけ反転ルック有するであろう\(\ sum_ {D = 1 } ^ nと\ MU(I)\ lfloor \ FRAC {N-} {I} \ rfloor \ lfloor \ FRAC {M} {I} \ rfloor \) 直接数論ブロックが、注意してください\(N当量10 ^ 9 \ \)をだからドゥはふるいシーク教える考える(\ムー\)\をし、
少しトリックは、我々は唯一のコンピューティングに行くだろうということです\(\ミュー\ NEQ 0 \ (D)) 剪定に直接、値を他の

#include<iostream>
#include<string>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define maxd 1000000007
#define eps 1e-8
#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
const int N=10000000;
struct node{
    int n,m,k;
};
bool operator <(node p,node q)
{
    if (p.n!=q.n) return p.n<q.n;
    else if (p.m!=q.m) return p.m<q.m;
    else return p.k<q.k;
}
map<node,ll> ans;
map<int,ll> sumu;
int n,m,k,tot=0,mu[N+10],pri[1001000],len;
bool nopri[N+10];
ll sum[N+10];
vector<int> fac;

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') && (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

void sieve()
{
    mu[1]=1;
    rep(i,2,N)
    {
        if (!nopri[i]) {pri[++tot]=i;mu[i]=-1;}
        int j;
        for (j=1;j<=tot && i*pri[j]<=N;j++)
        {
            nopri[i*pri[j]]=1;
            if (i%pri[j]==0) break;
            else mu[i*pri[j]]-=mu[i];
        }
    }
    rep(i,1,N) sum[i]=sum[i-1]+mu[i];
}

ll query(int x)
{
    if (x<=N) return sum[x];
    if (sumu[x]) return sumu[x];
    ll ans=1;int l,r;
    for (l=2;l<=x;l=r+1)
    {
        r=x/(x/l);
        ans-=1ll*(r-l+1)*query(x/l);
    }
    sumu[x]=ans;
    return ans;
}

ll calc(int n,int m)
{
    if (n>m) swap(n,m);
    //cout << n << " " << m << " ";
    int l,r;ll ans=0;
    for (l=1;l<=n;l=r+1)
    {
        r=min(n/(n/l),m/(m/l));
        ans+=1ll*(n/l)*(m/l)*(query(r)-query(l-1));
    }
    //cout << ans << endl;
    return ans;
}

ll solve(int n,int m,int k)
{
    if ((!n) || (!m)) return 0;
    node now=(node){n,m,k};
    if (ans[now]) return ans[now];
    if (k==1) ans[now]=calc(n,m);
    else
    {
        int i;
        for (i=0;i<len && fac[i]<=k;i++)
        {
            if ((k%fac[i]==0) && (mu[fac[i]]))
                ans[now]+=solve(m/fac[i],n,fac[i])*mu[fac[i]];
        }
    }
    return ans[now];
}

int main()
{
    n=read();m=read();k=read();
    sieve();
    rep(i,1,k)
        if (k%i==0) fac.pb(i);len=fac.size();
    printf("%lld",solve(n,m,k));
    return 0;
}

おすすめ

転載: www.cnblogs.com/encodetalker/p/11129975.html