HDU6053(72/600)

Problem Description
You are given an array A , and Zhu wants to know there are how many different array B satisfy the following conditions?

  • 1≤Bi≤Ai
  • For each pair( l , r ) (1≤l≤r≤n) , gcd(bl,bl+1…br)≥2

Input
The first line is an integer T(1≤T≤10) describe the number of test cases.

Each test case begins with an integer number n describe the size of array A.

Then a line contains n numbers describe each element of A

You can assume that 1≤n,Ai≤105

Output
For the kth test case , first output “Case #k: ” , then output an integer as answer in a single line . because the answer may be large , so you are only need to output answer mod 109+7

Sample Input
1
4
4 4 4 4

Sample Output
Case #1: 17

Source
2017 Multi-University Training Contest - Team 2

Recommend
liuyiding | We have carefully selected several similar problems for you: 6055 6054 6053 6052 6051

莫比烏斯反演的第一次用….
其實就是說莫比烏斯反演那個公式可以反過來用….
用大的算小的…

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=200105;
int normal[maxn];
int mu[maxn];
int prime[maxn];
int pcnt,u=0;
void Init()
{
    memset(normal,0,sizeof(normal));
    mu[1] = 1;
    pcnt = 0;
    for(int i=2; i<maxn; i++)
    {
        if(!normal[i])
        {
            prime[pcnt++] = i;
            mu[i] = -1;
        }
        for(int j=0; j<pcnt&&i*prime[j]<maxn; j++)
        {
            normal[i*prime[j]] = 1;
            if(i%prime[j]) mu[i*prime[j]] = -mu[i];
            else
            {
                mu[i*prime[j]] = 0;
                break;
            }
        }
    }
}
int tu[maxn],sum[maxn],n,q;
ll mo=1e9+7;
ll ksm(ll ds,ll zs)
{
    ll fs=1;
    while(zs)
    {
        if(zs&1)fs*=ds;

        fs%=mo;
        ds*=ds;
        ds+=mo;
        ds%=mo;
        zs>>=1; //cout<<zs<<endl;
    }
    return (fs+mo)%mo;
}
ll f[maxn],F[maxn];
int main()
{
    Init();
//  cout<<ksm(2,2)<<endl;
//  return 0;
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n;
        memset(f,0,sizeof(f));
        memset(F,0,sizeof(F));
        memset(tu,0,sizeof(tu));
        memset(sum,0,sizeof(sum));
        int shang=0,xia=1e9;
        for(int a=1;a<=n;a++)
        {
            scanf("%d",&q);
            tu[q]++;
            shang=max(shang,q);
            xia=min(xia,q);
        }
        for(int a=1;a<=200010;a++)
        {
            sum[a]=sum[a-1]+tu[a];
        }
        for(int a=2;a<=xia;a++)
        {
            F[a]=1;
            for(int b=a;b<=shang;b+=a)
            {
                int qj=b/a;
        //      int y=min(,shang);
            //  cout<<"ccccc";
    //      cout<<sum[y]-sum[b-1]<<endl<<qj<<endl;
                F[a]=(F[a]*ksm(qj,sum[b+a-1]-sum[b-1])%mo+mo)%mo;
            }//cout<<"asd";
        }
    //  return 0;
        for(int a=2;a<=xia;a++)
        {
            for(int b=1;;b++)
            {
                if(b*a>xia)break;
                f[a]=(f[a]+mu[b]*F[a*b]+mo)%mo;
            }
        }

        ll dan=0;
        for(int a=2;a<=xia;a++)
        {
            dan=(dan+f[a]+mo)%mo;
        }
        printf("Case #%d: %lld\n",++u,dan%mo);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章