問題の脳魔法の洞窟ソリューション - [HAOI2011]問題、B

【HAOI2011]問題B

話題の顔:

要件:

 

まず、問題を単純化します:

 

これが事実であるPOI2007ZAP、クエリ

セット:

 

見つけることができます

そして、:

 

メビウス反転行為

 

セットアップ

あります。

 問題を単純化するために、上記の式の答え

(F(TK))の後半は、ブロックで分割することができるので、全体的な時間計算量は(√N)であります

 

本当の問題に戻ります:

上記の意味式を考慮:I IN:1-N、J:1 - GCDの番号(i、J)= kのときに数Nの

明らかと除外を見つけることができます:

注:(M、N)を解きます=

すなわち、最終的な答えは、(B、D)-Solve(B、C-1)-Solve(-1、D)を解く+解決(-1、C-1)

コードは以下の通りであります:

書式#include <iostreamの> 
の#include <cstdioを>
 に#define int型はlong long int型
 使用して 名前空間はstdを、
int型のミュウ[ 50001 ]、VIS [ 50001 ]、PRI [ 50001 ];
int型、B、C、D、K、T、CNTと、
オイラー()
{
    miu[1]=1;
    for(int i=2;i<=50000;i++)
    {
        if(!vis[i])
        {
            ++cnt;
            pri[cnt]=i;
            miu[i]=-1;
        }
        for(int j=1;j<=cnt;j++)
        {
            if(pri[j]*i>50000)
                break;
            if(i%pri[j]==0)
            {
                vis[i*pri[j]]=1;
                miu[i*pri[j]]=0;
                break;
            }
            else
            {
                vis[i*pri[j]]=1;
                miu[i*pri[j]]=-miu[i];
            }
        }
    }
    for(int i=1;i<=50000;i++)
    {
        miu[i]+=miu[i-1];
    }
}
int Work(int n,int m)
{
    if(n>m)
        swap(n,m);
    int X=n/k,ans=0;
    for(int l=1,r;l<=X;l=r+1)
    {
        r=min(n/(n/l),m/(m/l));
        ans+=(miu[r]-miu[l-1])*(n/(l*k))*(m/(l*k));
    }
    return ans;
}
signed main()
{
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    scanf("%lld",&t);
    Euler();
    while(t--)
    {
        scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k);
        printf(" %のLLD \ n "、ワーク(B、D)-work(A- 1、D)-work(B、C- 1)+ワーク(A- 1、C- 1 ))。
    }
    リターン 0 ;
}

 

エンドSahua!

 

おすすめ

転載: www.cnblogs.com/XLINYIN/p/12370192.html