日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【无码专区6】球与盒子(数学线性筛)

發布時間:2023/12/3 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【无码专区6】球与盒子(数学线性筛) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

因為只有std,沒有自我實現,所以是無碼專區

主要是為了訓練思維能力

solution才是dls正解,但是因為只有潦草幾句,所以大部分會有我自己基于正解上面的算法實現過程,可能選擇的算法跟std中dls的實現不太一樣。

std可能也會帶有博主自己的注釋。

problem

nnn 個球放入 nnn 個盒子里面,每個盒子里恰好都有一個球,標號從 111 開始。

且盒子標號和里面裝的球的標號的因子個數必須相同。

答案對 500009500009500009 取模。多組數據。

T≤1e5,n≤1e9T\le 1e5,n\le 1e9T1e5,n1e9


我的想法

observation :因子數不同的之間互相獨立,因子數相同的之間方案數為階乘,所以實際上是不同因子數的方案數的乘積。

對于 70%70\%70%n≤1e6n\le 1e6n1e6 數據,可以線性篩預處理將所有數按照因子個數分類,然后計算即可。

多組數據肯定不能每次都 O(n)O(n)O(n) 的掃一遍。

將查詢的 nin_ini? 按升序排列,指針掃的時候將 iii 加入,就單獨處理 iii 因子個數那個集合的貢獻,很好維護。

observation:111 只能放在 111 里。

observation:質數之間可以互相放。

由整數的唯一標準分解,所有數都可以被若干個質數的冪表示。


solution

觀察到,模數是非常小的,不同于往常的大質數。

所以當 cntx≥modcnt_x\ge modcntx?mod 之后,答案一定為 000

cntx:cnt_x:cntx?: 因子數為 xxx 的個數。

最后答案為 ∏cntx!\prod cnt_x!cntx?!

通過打表發現,當 n≥2250000n\ge 2250000n2250000,就已經存在一個 cntx≥modcnt_x\ge modcntx?mod 了。

所以只需要在 n<2250000n<2250000n<2250000 時用線性篩求出每個數的因子數,乘上對應的 cntxcnt_xcntx?,當 n≥2250000n\ge 2250000n2250000 直接輸出 000 即可。

一般而言,當模數不是尋常的模數時,正解往往會隱藏在模數的性質背后。

當模數是常見的大質數,一般都是數學計算方案了。


std

#include <algorithm> #include <cassert> #include <cstdio> #include <cstdlib> #include <cctype> #include <cmath> #include <cstring> #include <iostream> #include <sstream> #include <string> #include <utility> #include <vector> #include <cassert> #include <ctime> #include <queue> using namespace std; #define VAR(a,b) __typeof(b) a=(b) #define REP(i,n) for(int _n=n, i=0;i<_n;++i) #define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i) #define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i) #define FOREACH(it,c) for(VAR(it,(c).begin());it!=(c).end();++it) #define ALL(c) (c).begin(),(c).end() #define TRACE(x) cerr << "TRACE(" #x ")" << endl; #define DEBUG(x) cerr << #x << " = " << x << endl;typedef long long LL; typedef unsigned long long ULL; const int INF = 1000000000; const LL INFLL = LL(INF) * LL(INF); template<class T> inline int size(const T &c) {return c.size(); } int rint() {int x;if (scanf("%d", &x) != 1)return -1;return x; } LL rLL() {LL x;if (scanf("%lld", &x) != 1)return -1;return x; }const int MOD = 500009; const int MAXN = 2250000;int main() {freopen("ball.in", "r", stdin);freopen("ball.out", "w", stdout);vector<int> ndivisors(MAXN + 1, 1);int p = 2;for (p = 2; p * p * p <= MAXN; ++p)if (ndivisors[p] == 1) {int pk = p;for (int k = 1;; ++k) {int mm = 0;for (int q = pk; q <= MAXN; q += pk) {++mm;if (mm == p)mm = 0;elsendivisors[q] *= k + 1;}LL pk2 = LL(pk) * p;if (pk2 > MAXN)break;pk = int(pk2);}}for (; p * p <= MAXN; ++p)if (ndivisors[p] == 1) {int pk = p;for (int k = 1; k <= 2; ++k) {int mm = 0;for (int q = pk; q <= MAXN; q += pk) {++mm;if (mm == p)mm = 0;elsendivisors[q] *= k + 1;}pk *= p;}}for (; p <= MAXN; ++p)if (ndivisors[p] == 1) {for (int q = p; q <= MAXN; q += p) {ndivisors[q] *= 2;}}vector<unsigned> cnt(MAXN + 1, 0);vector<unsigned> res(MAXN + 1, 0);res[0] = 1;for (int n = 1; n <= MAXN; ++n) {int d = ndivisors[n];++cnt[d];res[n] = res[n - 1] * (cnt[d] % 1024u) % unsigned(MOD);if (cnt[d] >= 1024u) {unsigned a = res[n - 1] * (cnt[d] >> 10) % unsigned(MOD);res[n] = (res[n] + (a << 10)) % unsigned(MOD);}if (res[n] == 0)break;}int ntc = rint();REP(tc, ntc) {int n = rint();int r = n <= MAXN ? res[n] : 0;printf("%d\n", r);} }

總結

以上是生活随笔為你收集整理的【无码专区6】球与盒子(数学线性筛)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。