当前位置: 首页 > news >正文

UVa 12384 Span

题目描述

给定一个包含nnn个整数的数组X1≤i≤nX_{1 \leq i \leq n}X1in,定义数组XXXspanSSS为一个长度为nnn的整数数组,其中SiS_iSi表示在XiX_iXi之前(包括XiX_iXi自身)连续满足所有元素都≤Xi\leq X_iXi的最大元素个数。数学表示如下:

Si=∣Ai∣,Ai={j≤i∣∀k(j≤k≤i) (Xk≤Xi)}. S_i = |A_i|, \quad A_i = \{j \leq i \mid \forall k (j \leq k \leq i) \ (X_k \leq X_i)\}.Si=Ai,Ai={jik(jki)(XkXi)}.

例如,X=[40,2,10,50,30,15]X = [40,2,10,50,30,15]X=[40,2,10,50,30,15]spanS=[1,1,2,4,1,1]S = [1,1,2,4,1,1]S=[1,1,2,4,1,1]

本题的特殊设定是:Xi=Pi mod mX_i = P_i \bmod mXi=Pimodm,其中PiP_iPi是第iii个素数。我们需要计算SSS的所有元素之和mmm的结果。

输入格式

  • 第一行一个整数TTT,表示测试用例个数。
  • 接下来TTT行,每行两个整数n,mn, mn,m,满足1≤n,m≤1051 \leq n, m \leq 10^51n,m105

输出格式

对于每个测试用例,输出一行一个整数:(∑i=1nSi) mod m\left(\sum_{i=1}^n S_i\right) \bmod m(i=1nSi)modm

样例输入

3 7 10 10 16 10 7

(实际格式应为每行两个数,这里只是紧凑写法)

样例输出

0 5 6

题目分析

1. 直接计算的复杂度

若直接按照定义计算SiS_iSi,需要向前扫描直到遇到一个大于XiX_iXi的数,时间复杂度O(n2)O(n^2)O(n2),当nnn达到10510^5105时不可接受。

2. 素数的获取

我们需要前nnn个素数。第10510^5105个素数大约是1.3×1061.3 \times 10^61.3×106,因此可以预先用埃氏筛(Sieve of Eratosthenes\texttt{Sieve of Eratosthenes}Sieve of Eratosthenes)生成2×1062 \times 10^62×106以内的所有素数,并存储到全局数组中。由于TTT最多可能为10510^5105,必须只预处理一次

3.Span的计算优化

观察SiS_iSi的含义:它等于从iii向左数,直到遇到第一个大于XiX_iXi的元素为止,这中间的元素个数(包括XiX_iXi自己)。这是一个经典的左边第一个更大元素问题,可以用单调栈O(n)O(n)O(n)时间内解决。

具体方法:

  • 维护一个单调递减栈(栈内元素的值从栈底到栈顶严格递减)。
  • 遍历i=0…n−1i = 0 \dots n-1i=0n1
    • 当栈非空且栈顶元素的值≤Xi\leq X_iXi时,弹出栈顶(因为这些元素无法成为比XiX_iXi大的左边界)。
    • 如果栈为空,说明左边所有元素都≤Xi\leq X_iXi,则Si=i+1S_i = i + 1Si=i+1
    • 否则,栈顶元素的下标jjj是左边第一个大于XiX_iXi的元素,则Si=i−jS_i = i - jSi=ij
    • iii入栈。

这个过程保证了每个元素最多入栈和出栈一次,因此总复杂度O(n)O(n)O(n)

4. 模运算的注意点

最终需要输出totalSum mod mtotalSum \bmod mtotalSummodm。注意totalSumtotalSumtotalSum可能很大(最大约n2n^2n2级别),应使用646464位整数(如long long\texttt{long long}long long)累加,避免溢出。


解题思路

整体流程

  1. 预处理素数
    使用埃氏筛,生成2×1062 \times 10^62×106以内的所有素数,存入全局数组primes\texttt{primes}primes

  2. 对每个测试用例

    • 读取n,mn, mn,m
    • 取前nnn个素数对mmm取模,得到数组XXX
    • 使用单调栈计算SiS_iSi并累加求和。
    • 输出sum mod msum \bmod msummodm

为什么素数范围取2×1062 \times 10^62×106

10510^5105个素数约为129970912997091299709,因此2×1062 \times 10^62×106足够生成前10510^5105个素数,且不会造成过多的时间开销。

时间复杂度

  • 筛法:O(Llog⁡log⁡L)O(L \log \log L)O(LloglogL),其中L=2×106L = 2 \times 10^6L=2×106
  • 每个测试用例:O(n)O(n)O(n)
  • 总复杂度:O(Llog⁡log⁡L+∑n)O(L \log \log L + \sum n)O(LloglogL+n),在10510^5105级别内可接受。

空间复杂度

  • 素数列表:约10510^5105个整数。
  • 每个测试用例临时数组XXXSSSO(n)O(n)O(n)

实现细节

  • 使用vector<bool>\texttt{vector<bool>}vector<bool>进行布尔标记以节省内存。
  • 使用stack<int>\texttt{stack<int>}stack<int>存储下标,维护单调性。
  • 输入输出使用scanf\texttt{scanf}scanf/printf\texttt{printf}printf提高效率。
  • 累加和用long long\texttt{long long}long long类型。

代码实现

// Span// UVa ID: 12384// Verdict: Accepted// Submission Date: 2026-05-25// UVa Run Time: 0.000s//// 版权所有(C)2026,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;// 全局素数列表vector<int>primes;// 埃氏筛,生成所有不超过 limit 的素数voidsieve(intlimit){vector<bool>isPrime(limit+1,true);isPrime[0]=isPrime[1]=false;for(inti=2;i<=limit;++i){if(isPrime[i]){primes.push_back(i);if((longlong)i*i<=limit){for(intj=i*i;j<=limit;j+=i)isPrime[j]=false;}}}}intmain(){// 预先生成足够多的素数(第 100000 个素数约 1299709,取 2e6 安全)constintMAX_PRIME_LIMIT=2000000;sieve(MAX_PRIME_LIMIT);intT;scanf("%d",&T);while(T--){intn,m;scanf("%d %d",&n,&m);// 步骤1:生成 X 数组vector<int>X(n);for(inti=0;i<n;++i)X[i]=primes[i]%m;// 步骤2:单调栈计算 spanvector<int>S(n);stack<int>st;// 存下标,维护 X[st] 递减longlongtotalSum=0;for(inti=0;i<n;++i){while(!st.empty()&&X[st.top()]<=X[i])st.pop();if(st.empty())S[i]=i+1;elseS[i]=i-st.top();st.push(i);totalSum+=S[i];}// 输出 sum % mprintf("%lld\n",totalSum%m);}return0;}

总结

本题综合了素数筛法单调栈两个经典算法。关键在于:

  • 一次性预处理素数,避免重复计算。
  • 利用单调栈将span的计算从O(n2)O(n^2)O(n2)优化到O(n)O(n)O(n)
  • 注意累加和的数据范围,防止溢出。

掌握这些技巧后,不仅能解决本题,也能应对许多与 “左边第一个更大 / 更小元素” 相关的题目。

http://www.jsqmd.com/news/915092/

相关文章:

  • 电商退款算法精度陷阱:Python Decimal 实战与促销引擎 trace 凭证设计
  • 别再死记硬背YAML了!手把手带你用Python代码‘画’出YOLOv5s的Backbone结构图
  • 告别单调终端!FinalShell SSH工具保姆级美化教程:自定义背景、字体、快捷键全搞定
  • 构建结构化ModelOps流水线:从模型到运营的工程化实践
  • 核电常规岛外来流动人员全域无感定位管控方案解析
  • 《Java 100 天进阶之路》第33篇:Java中的static关键字详解
  • 06-认知篇-对比-ILRuntime深度解析
  • 从《原神》到独立游戏:拆解Unity Quality设置里那些‘看不见’的优化选项(Texture Streaming/Mipmap篇)
  • 2026 钢丝网片厂家哪家好 钢筋网片源头生产厂家 电焊网片现货厂家采购指南 - 栗子测评
  • 配置范式演进:XML、JavaConfig 与 Spring Boot
  • FreeModbus避坑指南:在STM32F429上移植TCP/RTU时,线圈和寄存器到底怎么用?
  • 农业SLAM系统挑战与优化:从特征提取到多传感器融合
  • FinalShell快捷键效率翻倍秘籍:除了Ctrl+C/V,这些隐藏组合键让你告别鼠标点点点
  • 告别邮件轰炸!手把手教你用飞书机器人聚合处理特定主题邮件(支持QQ/163邮箱)
  • 企业级Agent落地全攻略,从POC试错到规模化落地的四阶段避坑实战
  • 别再到处找源了!保姆级教程:用清华镜像在Ubuntu 22.04上一步到位安装Anaconda
  • 构建数据驱动决策闭环:从分析思维到实战落地的完整指南
  • 告别手动编译:用Makefile一键搞定VCS和Verdi的联合仿真(附完整脚本)
  • 快手图片去水印工具结合多场景使用方式适配不同设备与操作需求 - 科技热点发布
  • 2026 桥梁支座生产厂家橡胶支座生产厂家各类支座产品性能全面测评 - 栗子测评
  • 别再只会生成黑白二维码了!用Python的qrcode库玩转彩色、圆角、带Logo的个性化二维码
  • 世界模型接棒语言模型,这家公司全球首创物理AGI“双金字塔”体系,通用机器人进入“家庭时代”
  • ARM嵌入式开发中启动文件与分散加载文件的协同验证机制
  • 07-认知篇-对比-xLua深度解析
  • 11.LeetCode 1004. 最大连续1的个数 III | 滑动窗口解法详解(Java)
  • 不只是ENVI:三种免费/开源工具将GDEM高程数据转为.dem格式的横向评测
  • 2026 合肥全城黄金回收服务 到店上门均可选择 - 合扬奢侈品交易中心
  • 2026 板式橡胶支座厂家盆式高阻尼橡胶支座及球型支座加工厂家综合排行 - 栗子测评
  • 给项目配纯音乐后,我把 AI 写歌/AI 做伴奏流程拆了一遍
  • 2026 各类防护网厂商整理对比围栏钢丝网直销厂家与体育场围网选购方向 - 栗子测评