TrickGCD
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
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
* 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
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
k
th 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题目大意:求有多少组可能使得满足题目要求先来解释样例:比4不大的满足条件的有2,3,4,而如果要区间内有共同的最大公约数的话就是2,4,样例有4个4,所以每一个有2种可能,即有 2*2*2*2=16种,然后还有一种3,3,3,3,最大公约数为3,所以有16+1=17(种) 所以我们可以想到的是容斥原理,2的倍数的加上3的倍数的减去2*3的倍数的,同理,加上5的倍数的减去2*5的倍数的,减去3*5的倍数的,再 加上2*3*5的倍数的,所以是莫比乌斯容斥,具体看代码详解:ac代码:#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #include<string> #define nl n<<1 #define nr (n<<1)|1 using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int>P; const int INF=0x3f3f3f3f; const ll INFF=0x3f3f3f3f3f3f3f3f; const double pi=acos(-1.0); const double eps=1e-9; const ll mod=1e9+7; ll mu[100005]; void mobius() { mu[1]=1; for(int i=1;i<=100000;i++) for(int j=i+i;j<=100000;j+=i) mu[j]-=mu[i]; } ll qpow(ll a,ll b) { ll ans=1; while(b) { if(b&1) ans=(ans*a)%mod; b>>=1; a=(a*a)%mod; } return ans; } ll sum[200005]; ll cnt[200005]; int main() { mobius();int ca=1; int t;scanf("%d",&t); while(t--) { memset(cnt,0,sizeof(cnt));int n; scanf("%d",&n);int maxx=INF; for(int i=1;i<=n;i++) { int x;scanf("%d",&x); cnt[x]++; maxx=min(maxx,x); } ll ans=0; for(int i=1;i<=200000;i++)sum[i]=sum[i-1]+cnt[i]; for(int i=2;i<=maxx;i++) { ll tmp=1; for(int j=1;j*i<=100000;j++) { tmp=(tmp*qpow((ll)j,sum[i*j+i-1]-sum[i*j-1]))%mod; } ans=(ans-tmp*mu[i]+mod)%mod; } printf("Case #%d: %lld\n",ca++,ans); } return 0; }
题目链接: 点击打开链接http://acm.hdu.edu.cn/showproblem.php?pid=6053