(多校02)hdu 6053 trickgcd (莫比乌斯函数)

来源:互联网 发布:mac必下的软件 编辑:程序博客网 时间:2024/06/07 22:10
题意:给出序列A,求不同的序列B的个数
序列B满足:  1. bi<ai     2.bi,bj 两两不互质
思路:将ai离散化存到num[]中,num[i]表示1-i范围内有多少个ai ,枚举每个gcd,考虑不同gcd之间重复的贡献,用莫比乌斯函数去重
第一次写莫比乌斯函数,记个板子。。
#include <iostream>using namespace std;#define mo  1000000007#define ll long long#include <math.h>#include <string.h>#include <string>#include <algorithm>#include <queue>ll pre[100005],n;ll num[200005],dat[100005];void init()  {      pre[1]=1;      for(ll i=1;i<=100000;i++){          for(ll j=i+i;j<=100000;j+=i){              pre[j]-=pre[i];          }      }  }  ll qmi(ll a,ll b){    ll tmp=a,ans=1;    while(b)    {        if(b&1)            ans=(ans*tmp)%mo;        tmp=(tmp*tmp)%mo;        b=b>>1;    }    return ans;}int main(){    int i,j,t,ct=1;    init();    cin>>t;    while(t--)    {        memset(num,0,sizeof(num));        cin>>n;        int mii=999999;        for(i=0;i<n;i++)        {            cin>>dat[i];            num[dat[i]]++;            mii=mii>dat[i]?dat[i]:mii;        }        for(i=1;i<200000;i++)            num[i]+=num[i-1];        ll ans=0;        for(i=2;i<=mii;i++)        {            ll cnm=1;            for(j=1;j*i<=100000;j++)            {                cnm=(cnm*qmi(j,num[(j+1)*i-1]-num[j*i-1]))%mo;            }            ans=(ans-(cnm*pre[i])%mo+mo)%mo;        }        cout<<"Case #"<<ct++<<": "<<ans<<endl;    }    return 0;}


原创粉丝点击