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

HJ139 小红的01子序列计数(hard)

  • 题目
  • 题解(4)
  • 讨论(2)
  • 排行

较难 通过率:13.63% 时间限制:1秒 空间限制:1024M

知识点动态规划

校招时部分企业笔试将禁止编程题跳出页面,为提前适应,练习时请使用在线自测,而非本地IDE。

描述

小红定义一个字符串的权值为,该字符串包含的 "01""01"子序列[1][1]的数量。

现在小红拿到了一个由字符 ‘0’‘0’ 和 ‘1’‘1’ 组成的字符串环(即最后一个字符下一个是第一个字符)。现在小红想知道,这个环的所有长度不小于 22 的连续子串[2][2]权值之和是多少?
由于答案可能很大,请将答案对 (109+7)(109+7) 取模后输出。

"01""01"子序列[1][1]为从原字符串中删除任意个(可以为零、可以为全部)字符得到的新字符串,字符串恰好为 "01""01"。
子串[2][2]为从原字符串中,连续的选择一段字符(可以全选、可以不选)得到的新字符串。在本题中,环上的子串为,任取两个下标 ll 和 rr,从 ll 不断向右取直到 rr 形成的连续子串;特殊的,若 r<lr<l,则会从 ll 向右取到最后一个字符,之后从第一个字符取到 rr。

输入描述:

第一行输入一个正整数 n(1≦n≦105)n(1≦n≦105) 代表字符串的长度。
第二行输入一个长度为 nn、由字符 ‘0’‘0’ 和 ‘1’‘1’ 构成的字符串 ss。

输出描述:

输出一个整数,代表所有长度不小于 22 的连续子串的权值之和。由于答案可能很大,请将答案对 (109+7)(109+7) 取模后输出。

示例1

输入:

3 001

复制输出:

4

复制说明:

在这个样例中,长度为 22 的连续子串有 33 个: ∙ ∙"00""00",权值为 00; ∙ ∙"01""01",权值为 11; ∙ ∙"10""10",权值为 00。 长度为 33 的连续子串有 33 个: ∙ ∙"001""001",权值为 22; ∙ ∙"010""010",权值为 11; ∙ ∙"100""100",权值为 00。 所有长度不小于 22 的连续子串的权值之和为 0+1+0+2+1+0=40+1+0+2+1+0=4 。
#include <iostream> #include <string> using namespace std; #define rep(i, a, b) for (int i = (a), _##i = (b); i <= _##i; ++i) using ll = long long; const int N = 1e5 + 5; const int mod = 1e9 + 7; // 全局变量 ll ans = 0; // 最终答案 ll sum = 0; // 当前窗口内0的数量,用于辅助更新 ll num0 = 0; // 当前窗口内0的数量 ll sum0 = 0; // 当前窗口内所有0的下标之和 ll num1 = 0; // 当前窗口内1的数量 ll sum1 = 0; // 当前窗口内"01"子序列数量 void solve() { int n; cin >> n; string s; cin >> s; // 为了模拟环形,把s复制一份自己接到自己后面,并在前面加空格使下标从1开始 s = " " + s + s; // 初始化滑动窗口,处理前n个字符 rep(i, 1, n) { if (s[i] == '0') { num0++; sum0 += i; } else { // s[i] == '1' num1++; sum1 += sum0; // 新加入的1,与之前所有0形成"01"子序列 sum += num0; // 统计出现过的0的数量 } } // 滑动窗口,处理后续n个字符 rep(i, n + 1, 2 * n) { // 移除窗口左端点元素 i - n 的影响 sum1 -= sum; // 去掉以移除元素为起点产生的贡献 sum0 -= num0; // 更新所有0下标和 if (s[i - n] == '0') { num0--; // 0数量减少 sum -= num1; // 0被移除,减少对后续1的贡献 } else { num1--; // 1数量减少 // 移除1不会影响sum } // 加入新的元素 s[i] if (s[i] == '0') { num0++; sum0 += n; // 加入0,位置视为n(窗口固定大小) } else { // s[i] == '1' num1++; sum1 += sum0; // 新加入的1,与已有0形成新子序列 sum += num0; // 0的数量影响sum } // 累加当前窗口的贡献 ans = (ans + sum1) % mod; } cout << ans << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int t = 1; // cin >> t; // 如果有多组测试数据可以打开 while (t--) { solve(); } return 0; }
http://www.jsqmd.com/news/514680/

相关文章:

  • Transformer代码实现2:手搓词嵌入层和位置编码
  • Phi-3-vision-128k-instruct在嵌入式视觉系统中的角色与通信协议设计
  • adb微信降级(无需root)
  • YOLOFuse实战指南:如何训练自己的RGB+红外数据集
  • XSS-Labs靶场通关秘籍:从入门到精通的20种绕过技巧
  • yz-bijini-cosplayGPU算力优化:RTX 4090显存碎片治理与CPU卸载实践
  • Halcon实战:巧用emphasize算子提升工业视觉检测清晰度
  • FPGA远程烧录bit流的实现与优化
  • Chrome 119+ 新功能实测:鼠标悬停就能看哪个标签页在“吃”内存,附省电模式设置技巧
  • 3步打造ESP32物联网环境监测系统:嵌入式开发者的终极指南
  • Qwen3.5-9B交通管理:道路图像分析+拥堵预测+调度建议生成系统
  • OpenClaw成本优化方案:GLM-4.7-Flash本地接口替代OpenAI
  • Linux 6.3内核嵌入式适配深度解析:ARM/RISC-V驱动与实时I/O优化
  • AIGlasses OS Pro 智能视觉系统数据库课程设计参考:智能安防监控管理系统
  • 局部放电中的PRPD图与相位同步详解
  • 魔兽争霸III终极修复指南:用WarcraftHelper解决10大常见问题
  • VASSAL开源桌游引擎完整指南:三步打造专属数字桌游世界
  • OpenClaw云端体验方案:通过ollama平台QwQ-32B镜像快速验证
  • RX8025高精度RTC芯片驱动开发与温度补偿原理
  • 别再手动拖拽.unitypackage了!Unity 2022+ UPM包管理保姆级入门与实战避坑指南
  • Midscene.js视觉驱动自动化:从技术原理到实战应用
  • Kali实战:手把手教你防御局域网ARP欺骗攻击(附检测脚本)
  • 2026乐山特色美食优质商家推荐榜:乐山旅游临江鳝丝推荐/乐山旅游必去景点/乐山旅游攻略/乐山旅游美食攻略/乐山最出名的临江鳝丝/选择指南 - 优质品牌商家
  • python+Django+Vue.js小说推荐系统 小说可视化 小说爬虫 Django框架 大数据毕业设计
  • 基于BIND9的内网权威DNS服务器部署实战指南
  • 当GCSC遇见双馈风机:电力电子硬核玩家的SSO对抗实录
  • 当scGPT遇上空间坐标:如何为你的Transformer模型注入位置信息(附实战代码)
  • ESP-DDS:面向ESP32的轻量级DDS-like嵌入式通信框架
  • MogFace人脸检测模型WebUI技术生态:从Transformer看AI模型发展趋势
  • 李宏毅OpenClaw技术全面解析:System Promp → Context Compression压缩策略