TrickGCD
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 875 Accepted Submission(s): 343
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
#include <algorithm>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
using namespace std;
typedef long long LL;
const int N = 200100+10;
const LL mod = 1e9+7;
LL mo[N], sum[2*N];
void mobius()
{
mo[1]=1;
for(int i=1;i<N;i++)
for(int j=i*2;j<N;j+=i)
mo[j]-=mo[i];
return ;
}
LL cal(LL x,LL n)
{
LL r=1;
while(n)
{
if(n&1) r=r*x%mod;
n>>=1;
x=x*x%mod;
}
return r;
}
int main()
{
int t, n, ncase=1;
mobius();
scanf("%d", &t);
while(t--)
{
int minx=N, maxx=0,x;
scanf("%d", &n);
memset(sum,0,sizeof(sum));
for(int i=0;i<n;i++)
{
scanf("%d", &x);
minx=min(minx,x);
sum[x]++;
}
for(int i=0;i<N;i++) sum[i]+=sum[i-1];
LL ans=0;
for(int i=2;i<=minx;i++)
{
LL tmp=1;
for(int j=1;i*j+i-1<N;j++)
{
tmp=((tmp%mod)*(cal((LL)j,sum[i*j+i-1]-sum[i*j-1])%mod))%mod;
}
ans=(ans-tmp*mo[i]+mod)%mod;//注意符号
}
printf("Case #%d: %lld\n",ncase++,ans);
}
return 0;
}