牛客小白月賽9: div.2 A(線性篩)
阿新 • • 發佈:2018-11-23
連結:https://ac.nowcoder.com/acm/contest/275/J
來源:牛客網
題目描述
定義 f(n,k) 表示將 n 拆分成 k 個有序正整數乘積的方案數。
給定 n,k,,求f(1,k)~f(n,k)
舉個例子,假設要求 f(4,3) ,因為
所以 f(4,3)=6 。
輸入描述:
第一行兩個正整數 n,k 。
輸出描述:
設,且gi ≥ 0,且gi儘可能的小 設 你只需要輸出T就行了
輸入
4 3
輸出
11
說明
f1,3=1,f2,3=3,f3,3=3,f4,3=6
有點懶,直接放下官網題解吧
那麼一個線性篩就搞定了
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<string> #include<math.h> #include<queue> #include<stack> #include<iostream> using namespace std; #define LL long long #define mod 1000000007 LL F[10000005], inv[686] = {0,1}; int cnt, flag[10000005], num[10000005], pri[1000005]; int main(void) { LL ans, n, i, j, k; scanf("%lld%lld", &n, &k); k %= mod; for(i=2;i<=666;i++) inv[i] = (mod-mod/i)*inv[mod%i]%mod; for(i=2;i<=10000000;i++) { if(flag[i]==0) { num[i] = 1; pri[++cnt] = i; F[i] = k; } for(j=1;j<=cnt&&i*pri[j]<=10000000;j++) { flag[i*pri[j]] = 1; if(i%pri[j]==0) { num[i*pri[j]] = num[i]+1; F[i*pri[j]] = F[i]*(num[i]+k)%mod*inv[num[i]+1]%mod; break; } else { num[i*pri[j]] = 1; F[i*pri[j]] = F[i]*k%mod; } } } ans = 0; F[1] = 1; for(i=1;i<=n;i++) ans ^= (F[i]+i)%mod; printf("%lld\n", ans); return 0; } /* 10000000 1000000000000000000 */