【bzoj1101】[POI2007]Zap

(markdown下題面排版好像很醜。。還是貼鏈接吧

題目鏈接

很顯然的莫比烏斯

很容易就能寫出式子:

f(d)=n<=min(a,b)d|n  F(n)μ(nd)
其中F(n)=anbn

但是這個式子顯然不可優化。。那麼考慮換一種形式

f(d)=D=1min(a,b)dF(Dd)μ(D)

然後考慮F(n) 這個式子裏有兩個向下取整。。。聯想一下因數個數就會知道可能會有大量連續的D 使得F(Dd) 相等

這些相等的值顯然可以一起算,可以把F(Dd) 從和式中取出來,然後後面的μ 用一個前綴和維護起來快速計算

然後就做完了==

代碼:

#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<cstring>
#include<cmath>
using namespace std;

typedef long long LL;

const int INF = 2147483647;
const int maxn = 50010;

LL crz;
int a,b,d;
int p[maxn],tot,mu[maxn],sum[maxn];
bool mark[maxn];

inline LL getint()
{
    LL ret = 0,f = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
        ret = ret * 10 + c - '0',c = getchar();
    return ret * f;
}

inline void init(int n)
{
    mu[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        if (!mark[i]) p[++tot] = i , mu[i] = -1;
        for (int j = 1; j <= tot; j++)
        {
            if (i * p[j] > n) break;
            mark[p[j] * i] = 1;
            if (i % p[j]) mu[p[j] * i] = -mu[i];
            else
            {
                mu[p[j] * i] = 0;
                break;
            }
        }
    }
    for (int i = 1; i <= n; i++)
        sum[i] = sum[i - 1] + mu[i];
}

inline LL cal(int a,int b,int D)
{
    int c = min(a / d,b / d);
    int na = a / D,nb = b / D;
    LL ret = 0;
    for (int d = 1; d != c;)
    {
        int nex = min(na / (na / (d + 1)),nb / (nb / (d + 1)));
        ret += 1ll * (na / nex) * (nb / nex) * (sum[nex] - sum[d]);
        d = nex;
    }
    ret += 1ll * mu[1] * (na / 1) * (nb / 1);
    return ret;
}

int main()
{
    #ifdef AMC
        freopen("AMC1.txt","r",stdin);
    #endif
    int n = getint();
    init(50000);
    for (int i = 1; i <= n; i++)
    {
        a = getint(); b = getint(); d = getint();
        printf("%lld\n",cal(a,b,d));
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章