基本是参考watashi写的 他的容斥写得好漂亮!!! Orz
 /**//*
题意:给出n个数ai 若di = (ai,bi),其中 x<=bi<=y,问s<=∑di<=t的方案数
n<=40 s,t<=2000 x,y<=10^9 ai<=10^6
首先di是ai的因子,枚举di
g = (a , b ) <==> 1 = ( a/g , b/g )
然后计算[1,y]内有多少个数是满足 1 = ( a/g , b/g ) , 用容斥做
对 a/g 分解质因数,然后答案就是 b/g - 与a/g不互素的

然后再dp求出 s<=∑di<=t 的方案数
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

const long long MOD = 1000000007LL;

vector<int> factor;

long long cal(int n, int x, int y)//很漂亮的容斥,递归写的 .
  {
if( n == 0 )return y / x;
return cal( n-1 , x , y) + cal( n-1 , x * (-factor[n-1]) , y);
}
// cal (x,i) == 1 | i<=y
long long cal( int x , int y )
  {
factor.clear();
for( int g = 2; g * g <= x; g++ )
 {
if( x % g == 0)
 {
factor.push_back( g );
while( x % g == 0 ) x /= g;
}
}
if( x > 1)factor.push_back( x );
return cal( factor.size() , 1, y );
}

int main()
  {
#ifdef ONLINE_JUDGE
#else
freopen( "in" , "r" , stdin );
#endif
int n, s, t, x, y, a;
while( ~scanf( "%d%d%d%d%d", &n, &s, &t, &x, &y ) )
 {
--x;//
vector< long long > dp( t +1 , 0);
dp[0] = 1;
for(int i = 1; i<= n; i ++)
 {
scanf("%d",&a);
vector< pair< int , long long > > VG;
for( int g = 1; g * g <= a; g++ )
 {
if( a % g )continue;
int _g = a / g;
VG.push_back( make_pair( g , cal( a / g , y / g ) - cal( a / g , x / g ) ) );
if( _g != g )// g != _g
VG.push_back( make_pair( _g , cal( a / _g , y / _g ) - cal( a / _g , x / _g ) ) );
}
for( int j = t ; j >= 0; j--)//这里需要j>=0因为要对于i>0,更新dp[0] = 0!!
 {
dp[j] = 0;
for(int ii = 0; ii < VG.size(); ii++)
 {
int val = VG[ii].first ;
long long num = VG[ii].second;
if( j < val )continue;
dp[j] = ( dp[j] + dp[j-val] * num )%MOD;
}
}
}
long long ans = 0;
for( int i = s; i <= t ; i++ )
ans = ( ans + dp[i] ) % MOD;
printf("%lld\n", ans);
}
return 0;
}
|