HDU 6053 TrickGCD 数论

来源:互联网 发布:乔丹新秀赛季数据 编辑:程序博客网 时间:2024/05/29 18:01

TrickGCD

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2532    Accepted Submission(s): 965


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

1BiAi
* For each pair( l , r ) (1lrn) , gcd(bl,bl+1...br)2
 

Input
The first line is an integer T(1T10) 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 1n,Ai105
 

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
144 4 4 4
 

Sample Output
Case #1: 17

题意:问能构造多少序列  满足1<=bi<=ai且gcd(ai)>=2


题解:莫比乌斯搞一搞

for i

i代表当前gcd是i的倍数

然后用莫比乌斯容斥一下


#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const ll mod=1000000007;ll quick(ll a,ll k){    ll ans=1;    while(k){        if(k&1)ans=ans*a%mod;        k/=2;        a=a*a%mod;    }    return ans;}int mu[100005],cas=0;void mobius(int mn){    mu[1]=1;    for(int i=1;i<=mn;i++){        for(int j=i+i;j<=mn;j+=i){            mu[j] -= mu[i];        }    }}ll a[200005],cnt[200005];int main(){    int t,cas=1;    mobius(100000);    scanf("%d",&t);    while(t--){        ll n,m,i,j;        ll mis=999999;        scanf("%lld",&n);        memset(cnt,0,sizeof(cnt));        memset(a,0,sizeof(a));        for(i=1;i<=n;i++){            ll x;            scanf("%lld",&x);            a[x]++;            mis=min(x,mis);        }        for(i=1;i<=200000;i++){            cnt[i]=cnt[i-1]+a[i];        }        ll ans=0;        for(i=2;i<=mis;i++){            ll temp=1;            for(j=1;i*j<=100000;j++){                temp=(temp*quick(j,cnt[i*j+i-1]-cnt[i*j-1])%mod);            }            ans=(ans-temp*mu[i]+mod)%mod;        }        printf("Case #%d: %lld\n",cas++,(ans%mod+mod)%mod);    }    return 0;}


原创粉丝点击