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

题解:P6009 [USACO20JAN] Non-Decreasing Subsequences P

Problem

Bessie 最近参加了一场 USACO 竞赛,遇到了以下问题。当然 Bessie 知道怎么做。那你呢?

考虑一个仅由范围在 \(1 \ldots K\)\(1 \leq K \leq 20\))之间的整数组成的长为 \(N\) 的序列 \(A_1,A_2, \ldots ,A_N\)\(1 \leq N \leq 5 \times 10^4\))。给定 \(Q\)\(1 \leq Q \leq 2 \times 10^5\) )个形式为 \([L_i,R_i]\)\(1 \leq L_i \leq R_i \leq N\))的询问。对于每个询问,计算 \(A_{L_i},A_{L_i+1}, \ldots ,A_{R_i}\) 中不下降子序列的数量模 \(10^9+7\) 的余数。

\(A_L,\ldots ,A_R\) 的一个不下降子序列是一组索引 (\(j_1,j_2, \ldots ,j_x\)),满足 \(L\le j_1<j_2<\ldots<j_x\le R\) 以及 \(A_{j_1}\le A_{j_2}\le \ldots \le A_{j_x}\)。确保你考虑了空子序列!

Sol

\(f_{i,j}\) 为考虑前 \(i\) 个,子序列结尾值为 \(j\) 方案数。有转移 \(f_{i, a_i} = f_{i-1, a_i} + \sum_{j \le a_i} f_{i-1, j}\),对于 \(j \ne a_i\)\(f_{i, j} = f_{i - 1, j}\)\(j\) 这一维很小,考虑矩阵优化。转移矩阵 \(A\) 等于:

\[\begin{bmatrix} 1&&&&&&& \\ &1&&&&&& \\ &&1&&&&& \\ &&&\ddots&&&&\\ 1&1&\dots&1&2&0&\cdots&0\\ &&&&&1&&\\ &&&&&&\ddots&\\ &&&&&&&1\\ \end{bmatrix} \]

推一下可以简单的得到逆矩阵。即单位矩阵第 \(a_i\) 行前面 \(a_i-1\) 个都是 \(-\frac12\) 然后剩下的是单位矩阵。直接做矩阵的前缀(逆)积是 \(nk^3\) 无法接受。发现有值的位置仅 \(O(k)\) 个,可以优化到 \(O(nk^2)\)。查询可以用 base 来乘是 \(k^2\),可以前缀和做到 \(O(k)\)

假如没有逆矩阵怎么做?

线段树维护矩阵是 \(O(nk^3)-O(k^2\log n)\)。猫树是 \(O(nk^3\log)-O(qk^2)\)。若使用分块减少预处理量,散点转移前缀和,也难以通过。

换个思路,直接使用线段树维护。节点存储开始为 \(x\),结束为 \(y\) 的答案。使用前缀和合并减到 \(O(k^2)\)。然后再使用猫树。空间 \(O(nk^2)\) 可以通过离线逐块处理(即变成分治)做到 \(O(k^2\log n)\)。时间复杂度 \(O(nk^2\log n + qk^2)\)

Code

代码是写的逆矩阵的。远古代码,还请见谅。

#include<bits/stdc++.h>
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int inf = 1e9 + 7, infi32 = 2147483647, mod = 1e9 + 7;
const ll INF = 1e18;const int N = 5e4 + 10, MAXK = 20 + 1, inv2 = (mod + 1) / 2;
int n, K, Q;
int a[N], sp[N][MAXK];
struct Matrix {int a[MAXK][MAXK];
} pre[N], ipre[N];int main() {ioscin >> n >> K;for (int i = 1; i <= n; i++) cin >> a[i];for (int i = 0; i <= K; i++)pre[0].a[i][i] = ipre[0].a[i][i] = 1;for (int i = 1; i <= n; i++) {pre[i] = pre[i - 1]; ipre[i] = ipre[i - 1];for (int j = 0; j <= K; j++)for (int k = 0; k <= a[i]; k++)pre[i].a[j][a[i]] = (pre[i].a[j][a[i]] + pre[i - 1].a[j][k]) % mod;for (int j = 0; j <= a[i]; j++)for (int k = 0; k <= K; k++)ipre[i].a[j][k] = (ipre[i].a[j][k] + 1ll * ipre[i - 1].a[a[i]][k] * (mod - inv2) % mod) % mod;for (int j = 0; j <= K; j++)for (int k = 0; k <= K; k++)sp[i][j] = (sp[i][j] + pre[i].a[j][k]) % mod;}cin >> Q;while (Q--) {int l, r, ans = 0; cin >> l >> r;for (int i = 0; i <= K; i++) ans = (ans + 1ll * ipre[l - 1].a[0][i] * sp[r][i] % mod) % mod;cout << ans << "\n";}return 0;
}
http://www.jsqmd.com/news/280309/

相关文章:

  • 【计算机毕设】Python高校学生学业预警系统论文
  • 期刊论文创作不再难!虎贲等考 AI 解锁从创作到见刊的高效路径
  • 【珍藏必读】Dify vs Coze:大模型开发平台全方位对比,从架构到部署助你快速选型
  • 我的第一个公开实战项目(XXX 用户中心系统)
  • 学术写作利器:9款免费用论文查重工具,每天无限次检测,省时又省力
  • 【计算机毕设】Python高校社团学生会管理系统
  • 【干货收藏】智能体开发实战:企业级架构设计与实现难点攻克
  • POMDP在AI中的应用前景与挑战
  • 导师严选2026 TOP8 AI论文平台:专科生毕业论文写作全测评
  • 精选9款不花钱的论文查重工具,每日可无限次检测,学术研究更顺畅
  • 分享一个开源的商城系统:SpringBoot + Vue +Redis + MyBatis 前后端分离技术栈
  • 9大免费论文查重工具推荐,每天不限次数使用,让学术写作更轻松高效
  • 7款AI论文写作神器解析:如何快速提升效率并避免论文重复问题
  • 基于stm32单片机的智能灌溉系统
  • AI论文写作工具精选7款:高效撰写与降低重复率的实用技巧分享
  • 基于STM32单片机的智慧病房系统
  • 零成本论文查重工具精选9款,支持每日无限次检测,学术写作更无忧
  • 基于stm32单片机的智能充电宝系统
  • 电商行业中的多维数据分析模型
  • STL练习
  • 学术写作必备:9大免费查重工具,每天无限次检测,提升论文质量更便捷
  • 基于stm32单片机的智能安防系统
  • 基于android的大学学校食堂点餐系统
  • 全网最全MBA必备AI论文写作软件TOP10测评
  • 基于android的个人健康系统
  • 无需付费的9款论文查重神器,24小时不限次数使用,为学术创作保驾护航
  • 【AI+教育】人机协同教学研究的五大落地路径
  • 基于stm32单片机的智能拐杖系统
  • 【毕业设计】Python高校社团学生会管理系统
  • 免费又好用的9个论文查重工具,支持每日无限检测,让学术写作事半功倍