UVa 11669 Non Decreasing Prime Sequence

发布时间:2026/7/22 9:43:52
UVa 11669 Non Decreasing Prime Sequence 题目描述非递减素数序列NDPS\texttt{NDPS}NDPS是一个由素数组成的序列满足第iii个元素不小于第i−1i - 1i−1个元素i1i 1i1。一个NDPS\texttt{NDPS}NDPS的权重定义为该序列所有元素的乘积。定义序列aaa小于序列bbb若aaa的元素个数小于bbb的元素个数若元素个数相同则按字典序比较。给定区间[A,B][A, B][A,B]A≤BA \le BA≤B需要找出所有权重在[A,B][A, B][A,B]范围内的NDPS\texttt{NDPS}NDPS中第KKK小的序列。输入格式第一行包含整数TTTT≤5000T \le 5000T≤5000表示测试用例数量。接下来TTT行每行三个整数AAA、BBB和KKK2≤A≤B≤10000002 \le A \le B \le 10000002≤A≤B≤1000000。保证至少存在KKK个符合条件的NDPS\texttt{NDPS}NDPS。输出格式对于每个测试用例输出一行格式为Case x:后接该用例的第KKK小NDPS\texttt{NDPS}NDPS序列元素之间用空格分隔。样例输入3 2 10 1 2 10 5 2 10 9样例输出Case 1: 2 Case 2: 2 2 Case 3: 2 2 2题目分析问题核心在于给定数值区间[A,B][A, B][A,B]需要枚举所有权重在该区间内的非递减素数序列并按照特定规则排序长度优先字典序次之然后输出第KKK个。直接枚举所有可能的素数序列不可行因为组合数量庞大。观察到序列的权重等于各素数的乘积且序列是非递减的这本质上对应着一个整数的质因数分解。任意一个正整数NNN将其质因数按非递减顺序排列恰好构成一个唯一的NDPS\texttt{NDPS}NDPS其乘积为NNN。例如N122×2×3N 12 2 \times 2 \times 3N122×2×3对应的NDPS\texttt{NDPS}NDPS就是[2, 2, 3]。因此题目转化为在区间[A,B][A, B][A,B]内的所有整数中对其质因数分解结果按非递减顺序排列的质因数序列进行排序排序规则为先比较序列长度即质因数个数含重数长度相同则比较字典序然后输出第KKK个序列。这样问题规模被压缩到B≤106B \le 10^6B≤106可枚举范围内的所有整数并预处理其质因数分解结果。解题思路预处理质因数分解首先使用线性筛法求出111到10610^6106内每个数的最小质因子spf\texttt{spf}spf。然后利用spf\texttt{spf}spf对每个数进行质因数分解将分解出的质数按非递减顺序存入factors[x]数组。由于分解过程本身保证了质因数按从小到大的顺序出现因此factors[x]天然就是一个非递减素数序列且其乘积恰好为xxx。排序规则与序列生成需要按照题目定义的顺序对所有x∈[2,106]x \in [2, 10^6]x∈[2,106]对应的序列进行全局排序。排序规则为序列长度即质因数个数较小者更小。若长度相同则按字典序比较序列。因此可构造一个包含所有整数222到10610^6106的数组order并使用自定义比较函数进行排序先比较factors[a].size()再比较factors[a]与factors[b]的字典序。区间查询优化由于T≤5000T \le 5000T≤5000若对每个测试用例都扫描整个order数组时间复杂度为O(T⋅N)O(T \cdot N)O(T⋅N)其中N106−1N 10^6 - 1N106−1可能超时。因此采用分块思想优化区间查询。将排序后的order数组分成若干块每块大小为blockSize\texttt{blockSize}blockSize取250025002500。对每个块将其中的元素按数值大小排序升序以便快速统计块内有多少个权重在[A,B][A, B][A,B]之间。对于每个查询(A,B,K)(A, B, K)(A,B,K)遍历所有块在块内使用lower_bound和upper_bound统计数值落在[A,B][A, B][A,B]内的元素个数。若累计个数达到KKK则在该块内部顺序扫描原始order块内的元素找到第KKK个满足权重条件的元素即为答案。这种方法将单次查询的复杂度降至O(块数⋅log⁡块大小块大小)O(\text{块数} \cdot \log \text{块大小} \text{块大小})O(块数⋅log块大小块大小)在给定数据范围内表现良好。正确性说明质因数分解的唯一性保证了每个NDPS\texttt{NDPS}NDPS与一个整数一一对应。全局排序的order数组严格按照题目定义的序列顺序排列因此区间查询时只需按该顺序选择第KKK个满足权重条件的元素。分块查询准确统计了区间内的元素个数并确保输出的是全局第KKK小的序列。复杂度分析预处理线性筛O(V)O(V)O(V)其中V106V 10^6V106。质因数分解O(Vlog⁡V)O(V \log V)O(VlogV)。全局排序O(Vlog⁡V⋅L)O(V \log V \cdot L)O(VlogV⋅L)其中LLL为分解结果的平均长度但比较操作在vector\texttt{vector}vector上开销较小。查询O(T⋅(VblockSize⋅log⁡blockSizeblockSize))O(T \cdot (\frac{V}{\text{blockSize}} \cdot \log \text{blockSize} \text{blockSize}))O(T⋅(blockSizeV​⋅logblockSizeblockSize))。空间复杂度O(V⋅L)O(V \cdot L)O(V⋅L)存储所有质因数分解结果。代码实现// Non Decreasing Prime Sequence// UVa ID: 11669// Verdict: Accepted// Submission Date: 2026-07-12// UVa Run Time: 0.730s//// 版权所有C2026邱秋。metaphysis # yeah dot net#includebits/stdc.husingnamespacestd;constintMAXV1000000;vectorintspf(MAXV1);vectorvectorintfactors(MAXV1);voidprecompute(){vectorintprimes;for(inti2;iMAXV;i){if(!spf[i]){spf[i]i;primes.push_back(i);}for(intp:primes){if(pspf[i]||1LL*i*pMAXV)break;spf[i*p]p;}}for(inti2;iMAXV;i){intxi;while(x1){intpspf[x];while(x%p0){factors[i].push_back(p);x/p;}}}}intmain(){ios::sync_with_stdio(false);cin.tie(nullptr);precompute();vectorintorder;order.reserve(MAXV-1);for(inti2;iMAXV;i)order.push_back(i);sort(order.begin(),order.end(),[](inta,intb){if(factors[a].size()!factors[b].size())returnfactors[a].size()factors[b].size();returnfactors[a]factors[b];});intN(int)order.size();intblockSize2500;intnumBlocks(NblockSize-1)/blockSize;vectorintblockStart(numBlocks),blockEnd(numBlocks);vectorvectorintblockSorted(numBlocks);for(intb0;bnumBlocks;b){intlb*blockSize;intrmin(N,lblockSize);blockStart[b]l;blockEnd[b]r;blockSorted[b].reserve(r-l);for(intil;ir;i)blockSorted[b].push_back(order[i]);sort(blockSorted[b].begin(),blockSorted[b].end());}intT;cinT;for(inttc1;tcT;tc){intA,B,K;cinABK;intans-1;intcnt0;for(intb0;bnumBlocks;b){autovecblockSorted[b];autoitLlower_bound(vec.begin(),vec.end(),A);autoitRupper_bound(vec.begin(),vec.end(),B);intnum(int)(itR-itL);if(cntnumK){intneedK-cnt;for(intiblockStart[b];iblockEnd[b];i){intworder[i];if(wAwB){--need;if(need0){answ;break;}}}break;}elsecntnum;}coutCase tc: ;constautofacfactors[ans];for(size_t i0;ifac.size();i){if(i)cout ;coutfac[i];}cout\n;}return0;}总结本题巧妙地将非递减素数序列问题转化为整数的质因数分解排序问题利用了算术基本定理中的唯一分解性。主要技巧包括模型转换将序列问题转化为整数及其质因数分解极大简化了问题结构。预处理与排序通过一次性预处理所有可能的序列并排序使得多次查询能够快速响应。分块优化在区间查询中引入分块平衡了时间与空间避免了O(T⋅N)O(T \cdot N)O(T⋅N)的线性扫描。该方法的核心在于将组合生成问题转化为静态数据上的查询问题适用于BBB较小10610^6106且查询次数较多的场景。掌握这种转化思想对处理类似的大规模枚举与排序问题具有重要参考价值。