hdu 6363 bookshelf
题解讲的很清楚了,直接看代码就懂了
题解:http://bestcoder.hdu.edu.cn/blog/2018-multi-university-training-contest-6-solutions-by-%e7%a6%8f%e5%b7%9e%e5%a4%a7%e5%ad%a6/
#include<stdio.h> #include<iostream> #include<vector> #include<string.h> #include<algorithm> #include<map> #include<queue> #include<cmath> #include<set> #include<map> #define de(x) cout<<#x<<"="<<x<<endl; #define dd(x) cout<<#x<<"="<<x<<" "; #define rep(i,a,b) for(int i=a;i<(b);++i) #define repd(i,a,b) for(int i=a;i>=(b);--i) #define repp(i,a,b,t) for(int i=a;i<(b);i+=t) #define mt(a,b) memset(a,b,sizeof(a)) #define fi first #define se second #define mp(u,v) make_pair(u,v) #define sz(a) (int)a.size() #define pb push_back #define PI acos(-1.0) #define qc std::ios::sync_with_stdio(false) #define all(a) a.begin(),a.end() using namespace std; typedef vector<int> vi; typedef long long ll; typedef double db; typedef pair<int,int> pii; const ll mod = 1e9+7; const int N = 2e6+6; const double eps = 1e-6; const int inf = 0x3f3f3f3f; bool eq(const db &a, const db &b) { return fabs(a - b) < eps; } bool ls(const db &a, const db &b) { return a + eps < b; } bool le(const db &a, const db &b) { return eq(a, b) || ls(a, b); } ll gcd(ll a,ll b) { return a==0?b:gcd(b%a,a); }; ll lcm(ll a,ll b) { return a/gcd(a,b)*b; } ll kpow(ll a,ll b) {ll res=1;a%=mod; if(b<0) return 1; for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} ll read(){ ll x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll inv[N], f[N], fac[N]; ll a[N]; void init() { f[0] = 1; f[1] = 2; fac[0] = fac[1] = 1; inv[1]=1; rep(i, 2, N) { fac[i] = fac[i-1] * (ll)i % mod; inv[i] = kpow(fac[i], mod-2); f[i] = (f[i-1] * f[i-2]) % mod; } } ll C(int n, int m) { if(n < m) return 0ll; if(m==0 || n==m) return 1ll; if(n-1==m || m==1) return n; return fac[n] * inv[m] % mod * inv[n-m] % mod; } int main(){ init(); int T; scanf("%d",&T); while(T--) { int n, m; scanf("%d%d",&n,&m); mt(a, 0); ll sum = C(n+m-1, n), ans = 0; repd(g,n,1) { if(n%g==0) { ll j = n / g; a[g] = C(j+m-1,j) % mod; repp(k,g+g,n + 1,g) a[g] = (a[g] - a[k] + mod) % mod; ans = ans + a[g] * (f[g] - 1 + mod) % mod; ans %= mod; } } ans = ans * kpow(sum, mod-2) % mod; printf("%lld\n",ans); } return 0; }