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

题解:P3336 [ZJOI2013] 话旧

原题链接

解析

首先明确极小值的含义,形象地说就是山谷,在本题中表现为函数值一旦下降则必定会下降至 0。

进一步读题发现所谓“在 \((I,I+1)\) 上是斜率为 \(1\)\(−1\) 的一次函数”其实就是点 \((I,y)\) 走到点 \((I,y + 1)\) 或点 \((I,y-1)\)

定点将函数划分成了若干个区间,我们一个区间一个区间来考虑。设 \(v_i\) 为第 \(i\) 个顶点,设 \(g_i\) 表示以 \(x_i\)\(x_{i - 1}\) 为端点的区间中,合法图像个数。但是此时我们发现如果到达第 \(v_{i - 1}\) 的那一步如果是往下走的,那么只要 \(f(x_{i - 1}) > 0\),这个区间为了满足极小值限制也得往下走。所以多加一维状态 \(g_{i,0/1}\) 表示到达 \(v_{i}\) 时是 往下走/往上走。

考虑如何转移,下面默认只讨论一般情况。

  • \(g_{i,0}\)\(g_{i - 1,0}\) 转移。

    画个图先。

    可以发现图像中会出现若干个山峰(红色和紫色也算)除去这些山峰后会出现一个对高度作 \(\lvert f(x_i) - f(x_{i - 1})\rvert\) 的贡献的连续段,所以在山峰上消耗的步数为总步数 \(x_i - x_{i - 1}\) 减去高度差 \(\lvert f(x_i) - f(x_{i - 1})\rvert\),记为 \(c\)。对高度做贡献的连续段的位置是确定的,必定在最后一个山峰之前或第一个山峰之前,取决于相对高度;类似红色段的山峰必定存在且高度一定,现在问题在于剩余山峰的个数以及高度。按照每个山峰考虑,一个高度为 \(h\) 的山峰需要 \(2h\) 的步数,总共可支配 \(c - 2\min(f(x_i),f(x_{i - 1}))\) 步。求方案数考虑插板,但是这里有限制每个板之间的间隔必须为偶数,所以不妨将一个元素视为两步,总共 \(\frac{c - 2\min(f(x_i),f(x_{i - 1}))}{2}\) 个元素,记为 \(m\),这样就变为普通插板了。山峰个数,即插的板数 \(+1\) 可以是 \([1,m]\),插 \(i\) 个板的方案数是 \(\tbinom{m - 1}{i}\),总方案数就是 \(\sum_{i=0}^{m - 1} \tbinom{m - 1}{i}=2^{m - 1}-1\),但是可能只有一个红色山峰,即其余山峰个数为 \(0\),所以最终方案数为 \(2 ^ {m - 1}\)

  • \(g_{i,0}\)\(g_{i - 1,1}\) 转移。

    区别在于没有了开始必须向下走的限制。

    考虑向上走,按照类似的方法画图分析得到同样有一个类似的高度固定为 \(f(x_{i - 1})\) 的山峰,于是总方案数的计算方式是一样的,向下走更是一样。

  • \(g_{i,1}\)\(g_{i - 1,0}\) 转移和从 \(g_{i - 1,1}\) 转移。

    画图之后可以发现计算方式是完全一致的。

  • 特判。

    • \(g_{i - 1,0}\) 转移时, \(f(x_{i - 1}) = 0\) 的情况。
    • 图像只能为一条直线,没有山峰的情况。
    • \(m<0\)\(m=0\) 的情况。
    • 后面忘了。

现在来处理第二问,其实就是个贪心,尽量把向上的堆在一起走,但是细节巨多。

时间复杂度 \(O(n\log n)\)

话说数据貌似保证有解。

代码

你确定要看吗?

#include <bits/stdc++.h>
#define ls(p) ((p) << 1)
#define rs(p) (((p) << 1) | 1)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 1e6 + 5,M = 100 + 5,mod = 19940417;
int g[N][2],x[N],fx[N],mx[N][2];
bool b[N][2];//表示该状态是否合法
int qmi(int a,int b){int res = 1;while(b){if(b & 1) res = 1ll * res * a % mod;a = 1ll * a * a % mod;b >>= 1;}return res;
}
map<int,int> m;
int main(){ios::sync_with_stdio(false);cin.tie(0);
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);int n,k;cin>>n>>k;m[0] = m[n] = 0;for(int i=1;i<=k;i++){cin>>x[i]>>fx[i];if(m.count(x[i]) && m[x[i]] != fx[i]){cout<<0; return 0;}m[x[i]] = fx[i];}vector<pii> v;for(auto it = m.begin();it != m.end();it++){v.push_back(*it);}g[0][0] = 1;b[0][0] = true;for(int i=1;i<v.size();i++){mx[i][1] = mx[i][0] = v[i].second;int c = v[i].first - v[i - 1].first - abs(v[i].second - v[i - 1].second);if(!c){if(v[i].second > v[i - 1].second){g[i][1] = g[i - 1][0] * (v[i - 1].second == 0) + g[i - 1][1];g[i][1] %= mod;b[i][1] |= b[i - 1][0] & (v[i - 1].second == 0) | b[i - 1][1];if(b[i - 1][0] && !v[i - 1].second) mx[i][1] = max(mx[i][1],mx[i - 1][0]);if(b[i - 1][1]) mx[i][1] = max(mx[i][1],mx[i - 1][1]);}if(v[i].second < v[i - 1].second){g[i][0] = g[i - 1][0] + g[i - 1][1];g[i][0] %= mod;b[i][0] |= b[i - 1][0] | b[i - 1][1];if(b[i - 1][0]) mx[i][0] = max(mx[i][0],mx[i - 1][0]);if(b[i - 1][1]) mx[i][0] = max(mx[i][0],mx[i - 1][1]);}continue;}if(c < 0 || (c - 2 * min(v[i - 1].second,v[i].second)) % 2){cout<<0;		return 0;}int m = (c - 2 * min(v[i - 1].second,v[i].second)) / 2;if(m < 0){g[i][0] = g[i - 1][0] * (v[i - 1].second == 0) + g[i - 1][1];g[i][0] %= mod;b[i][0] |= b[i - 1][0] | b[i - 1][1];if(b[i][0]) mx[i][0] = max(mx[i][0],c / 2 + max(v[i].second,v[i - 1].second));if(b[i - 1][0]){mx[i][0] = max(mx[i][0],mx[i - 1][0]);}if(b[i - 1][1]){mx[i][0] = max(mx[i][0],mx[i - 1][1]);}continue;}else if(!m){g[i][1] = g[i - 1][0] + g[i - 1][1];	g[i][0] = g[i - 1][0] * (v[i - 1].second == 0) + g[i - 1][1];g[i][1] %= mod;g[i][0] %= mod;b[i][1] |= b[i - 1][0] | b[i - 1][1];b[i][0] |= b[i - 1][0] | b[i - 1][1];if(b[i][0]){if(b[i - 1][1] || b[i - 1][0] && v[i - 1].second == 0)mx[i][0] = max(mx[i][0],c / 2 + max(v[i].second,v[i - 1].second));}if(b[i - 1][0]){mx[i][0] = max(mx[i][0],mx[i - 1][0]);mx[i][1] = max(mx[i][1],mx[i - 1][0]);}if(b[i - 1][1]){mx[i][0] = max(mx[i][0],mx[i - 1][1]);mx[i][1] = max(mx[i][1],mx[i - 1][1]);}continue;}g[i][0] = 1ll * g[i - 1][0] * qmi(2,m - 1) % mod + 1ll * g[i - 1][1] * qmi(2,m) % mod;g[i][0] %= mod;b[i][0] |= b[i - 1][0] | b[i - 1][1];if(b[i - 1][0]){mx[i][0] = max(mx[i][0],mx[i - 1][0]);if(!v[i - 1].second){mx[i][0] = max(mx[i][0],max(v[i].second,v[i - 1].second) + m);}else{mx[i][0] = max(mx[i][0],v[i].second + m);}}if(b[i - 1][1]){mx[i][0] = max(mx[i][0],mx[i - 1][1]);mx[i][0] = max(mx[i][0],v[i - 1].second + m);mx[i][0] = max(mx[i][0],v[i].second + m);}if(v[i].second != 0){g[i][1] = 1ll * g[i - 1][0] * qmi(2,m - 1) % mod + 1ll * g[i - 1][1] * qmi(2,m) % mod;g[i][1] %= mod;b[i][1] |= b[i - 1][0] | b[i - 1][1]; if(b[i - 1][0]){mx[i][1] = max(mx[i][1],mx[i - 1][0]);if(!v[i - 1].second){mx[i][1] = max(mx[i][1],v[i - 1].second + m);}mx[i][1] = max(mx[i][1],m);}if(b[i - 1][1]){mx[i][1] = max(mx[i][1],v[i - 1].second + m);mx[i][1] = max(mx[i][1],mx[i - 1][1]);}}}cout<<g[v.size() - 1][0]<<" "<<mx[v.size() - 1][0];return 0;
}
http://www.jsqmd.com/news/621819/

相关文章:

  • 项目二:ABB IRB 120 三种运动仿真实验
  • Qwen3Guard-Gen-WEB部署指南:快速实现AI生成内容安全过滤
  • 一道基础计算题卡在 分,求助判题规则问题写
  • JOULWATT杰华特 JW5027SOTB#TRPBF SOT23-6 电压转换器
  • OpenClaw最强对手Hermes Agent从入门到精通
  • Node.js实战:利用阿里云短信服务实现高效验证码发送
  • 什么是 Transformer 架构?
  • 2026年4月,参考重型货架源头厂家口碑推荐选货,物流货架/仓库货架/大仓库货架/货架厂仓储货架,重型货架公司推荐 - 品牌推荐师
  • OpenSSL命令行生存指南:从生成RSA密钥到文件签名验签的完整流程
  • 深度技术剖析:PVZ Toolkit开源游戏修改器完全指南
  • L293D直流电机驱动库:跨平台HAL设计与直通防护
  • 基于PyTorch 2.8 与Dify框架的低代码AI应用开发
  • ZYNQ7000 AXI DMA 接收中断(S2MM_introut)全解析:从硬件原理到Linux驱动开发
  • Python 里把 JSON 转成字典
  • 2026年评价高的门窗/阳光房门窗/佛山智能门窗/极窄门窗优质公司推荐 - 品牌宣传支持者
  • Python 列表与元组:从核心区别到实战选型
  • 保姆级教程:用ABAP BAPI_PRODORDCONF_CREATE_TT实现多工序报工与自动收货(含完整代码)
  • [具身智能-336]:Python定义一个函数示例说明,不带参数和带参数分别说说明,还有->提示
  • 组合专机-给喷油泵下体零件设计组合机床(论文 CAD图纸)
  • TMI拓尔微 TMI3408 SOT23-5 DC-DC电源芯片
  • F12实战:Cookie的增删改查与登录态管理
  • FireRed-OCR Studio惊艳案例:将200页技术手册PDF转为可搜索Markdown
  • 2026年防爆地磅选型指南:地磅汽车衡/地磅电子汽车衡/地磅电子秤/地磅衡器/天津地磅/天津电子秤/工业电子秤/选择指南 - 优质品牌商家
  • ImageNet验证集标签映射实战:从devkit解析到文件重组织的完整指南
  • RS-422 vs RS-485:硬件工程师必须知道的5个关键差异点
  • 彻底告别OpenClaw使用焦虑:我给他装上了“透视眼”和“批量克隆模组手
  • 一个LLM网关需要处理哪些工程问题?多模型路由与成本归因实战
  • 【内部流出】某TOP3电商Loom迁移白皮书精要版(含GC调优参数、监控埋点规范、5类典型Case复盘)
  • 5G专网外场UDP灌包实战:从iperf命令到峰值速率验证
  • 2026年热门的大白菜包装机/叶菜包装机/青岛鸡排包装机/鸡排包装机厂家推荐与选型指南 - 品牌宣传支持者