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

CF1286E

很牛的题。

定义一个 border 的权值为这个 border 对应后缀的 \(w\) 的最小值。考虑每次加入一个字符后答案的增量,等于加入后所有 border 的权值和。

假设当前加入字符 \(c\),首先如果 \(s_0 = c\),新增一个长度为 \(1\) 的 border,另外,如果一个 border 对应前缀的下一个字符不是 \(c\),则这个 border 需要删除。怎么找要删的 border 呢,我们考虑 fail 树,即 \(i\)\(nxt_i\) 连边,记 \(anc_i\) 表示 \(i\) 的祖先中第一个后继字符和 \(c\) 不同的 border,暴力删除,可以使用单调栈上二分求其权值。由于最多加入 \(n\) 个 border,所以均摊下来每次删除 \(\mathcal{O}(1)\) 个。

不被删除的 border 都会往后拓展,那么如果其权值 \(> w_i\) 就需要修改为 \(w_i\),开一个 map 暴力跳是对的,因为总共有 \(\mathcal{O}(n)\)\(w\),每次修改至少减少一种。

时间复杂度 \(\mathcal{O}(n \log n)\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
typedef pair<int, int> pii;
const int N = 6e5 + 10, mod = 998244353;
template<typename T>
void dbg(const T &t) { cout << t << endl; }
template<typename Type, typename... Types>
void dbg(const Type& arg, const Types&... args) {cout << arg << ' ';dbg(args...);
}
namespace Loop1st {
int n, nxt[N], anc[N], w[N];
char c;
ll sum;
i128 ans;
vector<int>stk;
string s;
map<int, int>cnt;
int ask(int pos) {return w[*lower_bound(stk.begin(), stk.end(), pos)];
}
void print(i128 num) {if (num >= 10) print(num / 10);cout << (int)(num % 10);
}
void main() {cin >> n;cin >> c >> w[0];s += c;stk.push_back(0);ans = w[0];cout << w[0] << '\n';for (int i = 1, j = 0; i < n; i++) {cin >> c >> w[i];c = (ans + c - 'a') % 26 + 'a';w[i] ^= ans & ((1 << 30) - 1);s += c;while (j && s[j] != c) j = nxt[j];if (s[j] == c) j++;nxt[i + 1] = j;if (c == s[nxt[i]]) anc[i] = anc[nxt[i]];else anc[i] = nxt[i];for (int k = i; k;) {if (s[k] == c) k = anc[k];else {int v = ask(i - k); // 删除一个长度为 k 的 border, 查询 [i - k, i - 1] 的后缀 mincnt[v]--;sum -= v;if (!cnt[v]) cnt.erase(v);k = nxt[k];}}if (s[0] == c) cnt[w[i]]++, sum += w[i];while (!stk.empty() && w[stk.back()] >= w[i]) stk.pop_back();stk.push_back(i);int del = 0;for (auto it = cnt.upper_bound(w[i]); it != cnt.end(); ) {auto [x, y] = *it;del += y;sum -= (ll)y * (x - w[i]);auto tmp = next(it);cnt.erase(it);it = tmp;}cnt[w[i]] += del;ans += sum + w[stk[0]]; // 别忘了整个串也要统计print(ans);cout << '\n';}
}}
int main() {// freopen("data.in", "r", stdin);// freopen("data.out", "w", stdout);ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);int T = 1;// cin >> T;while (T--) Loop1st::main();return 0;
}
// start coding at 13:53
// finish debugging at 14:33
http://www.jsqmd.com/news/205701/

相关文章:

  • elasticsearch增删改查索引结构示例 - 详解
  • 2025年杭州精装修大平层设计公司权威推荐:精装修全案设计/精装房改造/精装修全屋定制源头服务商精选 - 品牌推荐官
  • 【深度学习】YOLO实战之模型训练
  • AI Agent 时代全攻略:大模型+智能体,编程开发者的最强外挂,收藏这一篇就够了!
  • Twitter Shorts 的封面图设计吸引点击技巧是什么?
  • 机器人关节多维力试验机/传动系统总成效率试验机/制动系统总成效率试验机/传动机构运动工况模拟试验机哪个品牌更强?有没有资深采购能给点推荐? - 品牌推荐大师
  • 2026年1000元支付宝立减金回收多少,各面值价格表 - 淘淘收小程序
  • 2026执医技能通关攻略:高效工具+核心操作+避坑指南,助你一次过! - 品牌测评鉴赏家
  • CentOS 7 新磁盘LVM挂载详细步骤
  • 基于博弈与需求响应模型的光伏用户群电能共享方法探索
  • SWMM深度二次开发专题8:网络分析-最短路径查询
  • 跨境家具的海外仓安装教程广告互动形式是什么?
  • 2025年碳化硅品牌口碑榜:这些品牌为何备受青睐?磨料/不锈钢灰/棕刚玉/铬刚玉/碳化硅/黑碳化硅,碳化硅定制口碑推荐 - 品牌推荐师
  • 西门子840D HMI ADVANCED PC版:数控与PLC数据备份恢复、伺服调试、参数设定...
  • 转速恒压频比交流变频调速系统Simulink仿真
  • 点阵数码管显示屏驱动LED显示驱动芯片VK1S68C 数显驱动器原厂【FAE技术支持】
  • 安防监控视频汇聚平台EasyCVR打造出入口匝道安全畅行智慧管理方案
  • paperzz 开题报告:AI 工具如何把 “开题焦虑” 变成 “一键搞定”?
  • 程序员必看!大模型技术学习路径与实战指南,建议收藏
  • JAVA打造:同城服务预约陪诊医院陪护系统
  • centos7安装redis3.0以及phpredis扩展
  • 2026切割锯条品牌厂家TOP5权威推荐:定制实力厂商深度测评 - 工业品牌热点
  • 2026年北京配近视眼镜店服务排名,靠谱近视眼镜店服务选哪家推荐 - 工业设备
  • 找不到工作就好好学一下这份16W字Java面试合集
  • 100道软件功能测试面试题(针对刚毕业的人员)
  • Photoshop AVIF插件全面解析:开启图像压缩新纪元
  • 楼宇ICT规划实施标准:公区架构、基础设施与管理的稳定性保障
  • 2026年数控锯床供应商推荐,数控锯床靠谱生产商与不错的数控锯床工厂全解析 - 工业推荐榜
  • ComfyUI集成Z-Image全流程:可视化节点操作让AI绘画更高效
  • 超详细的常见漏洞代码审计方法,网络安全必看的零基础入门到精通教程!