5054. 统计
来源:互联网 发布:网络教育网 编辑:程序博客网 时间:2024/06/05 15:46
题目大意
给定
a 中共有k 个元素a[i]∈[1,n] ∀i∈[1,k),a[i]≤a[i+1] gcd(a1,a2...ak)=1
答案取模
Data Constraint
题解
显然可以莫比乌斯反演。设
的⽅案数。那么
现在的问题就类似将
然后这个反演显然可以在
杜教筛
杜教筛预处理
记
首先对于
所以
枚举约数
提出一个
然后就能递归求
对于较小的
SRC
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>using namespace std ;#define N 100000 + 10#define M 10000000 + 10typedef long long ll ;const int MO = 1e9 + 7 ;const int UP = 1e7 ;bool flag[M] ;int fac[N] , _fac[N] ;int Pri[M] , mu[M] , Sum[M] ;int tag[N] , f[N] ;int T , n , k , Con , ans ;int gcd( int x , int y ) { return y == 0 ? x : gcd( y , x % y ) ; }int Power( int x , int k ) { int s = 1 ; while ( k ) { if ( k & 1 ) s = (ll)s * x % MO ; x = (ll)x * x % MO ; k /= 2 ; } return s ;}void Pre() { fac[0] = _fac[0] = 1 ; for (int i = 1 ; i <= 100000 ; i ++ ) { fac[i] = (ll)fac[i-1] * i % MO ; _fac[i] = Power( fac[i] , MO - 2 ) ; } mu[1] = 1 ; for (int i = 2 ; i <= UP ; i ++ ) { if ( !flag[i] ) { Pri[++Pri[0]] = i ; mu[i] = -1 ; } for (int j = 1 ; j <= Pri[0] ; j ++ ) { if ( 1ll * i * Pri[j] > UP ) break ; flag[i*Pri[j]] = 1 ; if ( i % Pri[j] == 0 ) { mu[i*Pri[j]] = 0 ; break ; } mu[i*Pri[j]] = -mu[i] ; } } for (int i = 1 ; i <= UP ; i ++ ) Sum[i] = (Sum[i-1] + mu[i] + MO) % MO ;}ll C( int n , int m ) { if ( n <= 100000 && m <= 100000 ) return (ll)fac[n] * _fac[m] % MO * _fac[n-m] % MO ; ll ret = _fac[k] ; for (int i = n - k + 1 ; i <= n ; i ++ ) ret = ret * i % MO ; return ret ;}ll CalcSum( int x ) { if ( x <= UP ) return Sum[x] ; int t = x <= Con ? x : n / x + Con ; if ( tag[t] == T ) return f[t] ; ll ret = 1 ; for (int d = 2 ; d <= x ; d ++ ) { int r = x / (x / d) ; ret = ((ret - CalcSum(x/d) * (r - d + 1) % MO) % MO + MO) % MO ; d = r ; } tag[t] = T ; return f[t] = ret ;}void Mobius() { ll ret = 0 ; for (ll d = 1 ; d <= n ; d ++ ) { int r = n / (n / d) ; CalcSum(r) ; ret = ((ret + 1ll * (CalcSum(r) - CalcSum(d-1) + MO) % MO * C( n / d + k - 1 , k ) % MO) % MO + MO) % MO ; C( n / d + k - 1 , k ) ; d = r ; } printf( "%lld\n" , ret ) ;}int main() { freopen( "count.in" , "r" , stdin ) ; freopen( "count.out" , "w" , stdout ) ; memset( tag , -1 , sizeof(tag) ) ; scanf( "%d" , &T ) ; Pre() ; while ( T -- ) { scanf( "%d%d" , &n , &k ) ; Con = sqrt(n) ; Mobius() ; } return 0 ;}
以上.
1 0
- 5054. 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 统计
- 你为什么玩游戏?
- 冒泡排序
- LeetCode 557 Reverse Words in a String III(逆转字符串)
- 【数据结构】——-栈、队列和数组(三)
- 反腐网站搭建
- 5054. 统计
- Android面试题及答案(详细整理)
- JAVA泛型使用练习2(自定义泛型使用)
- 栈的使用(JavaScript)
- Hadoop 中文编码相关问题 -- mapreduce程序处理GBK编码数据并输出GBK编码数据
- 练习
- poj 1088 滑雪(简单dp)
- Java打印空心菱形,非常简单的操作
- Android studio[INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]