HDU6053 前缀和+容斥

来源:互联网 发布:淘宝官方电话人工服务 编辑:程序博客网 时间:2024/06/14 18:07
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>using namespace std;typedef long long ll;const int MAXN=2e5+10;const ll mod=1e9+7;ll dp[MAXN];ll cnt[MAXN],a[MAXN],n;//cnt[MAXN]1到i的a[i]的个数 ll fsm(ll x,ll n){ll s=1;while(n){if(n&1)s=(s*x)%mod;n>>=1;x=(x*x)%mod;}return s%mod;}int main(){int t;int cas=1;ll ans;ll res;scanf("%d",&t);while(t--){memset(dp,0,sizeof(dp));memset(cnt,0,sizeof(cnt));ll mxn=0;scanf("%d",&n);for(int i=0;i<n;i++){scanf("%lld",&a[i]);mxn=max(mxn,a[i]);cnt[a[i]]++;}for(int i=1;i<=mxn;i++)cnt[i]+=cnt[i-1];ans=0;for(int i=mxn;i>=2;i--){res=1;if(cnt[i-1]){dp[i]=0;continue;}for(int j=i;j<=mxn;j+=i){ll num=cnt[min(mxn,(ll)j+i-1)]-cnt[j-1];ll x=j/i;res=(res*fsm(x,num))%mod;} dp[i]=res;}for(int i=mxn;i>=2;i--){for(int j=i+i;j<=mxn;j+=i){dp[i]=(dp[i]-dp[j]+mod)%mod;}ans=(ans+dp[i])%mod;} printf("Case #%d: %lld\n",cas,ans); cas++;}return 0;}