HDU-6107 Typesetting(倍增法)
来源:互联网 发布:matlab2016b mac 编辑:程序博客网 时间:2024/06/05 20:59
传送门:HDU-6107
题解:ST算法
整片文章可以被分成2部分:①中间没有图片的部分;②中间插有图片的部分
可以将这2部分分别用ST离线,f[i][j]表示以第i个单词开始,连续1<<j行能写多少单词。要注意的是:在第②部分中,如果第一个单词的宽度大于dw和w-pw-dw的话,那么这一段f[i][j]=0
#include<bits/stdc++.h>#define FIN freopen("in.txt","r",stdin);using namespace std;typedef long long LL;const int MX = 1e5 + 5;const int inf = 0x3f3f3f3f;int mx, n, w, dw, pw, a[MX];int f1[MX][30]; //从第i个开始,占用1<<j行能容下的字符int f2[MX][30];void ST() { for (int i = 1; i <= n; i++) { int cnt = a[i], j = i + 1; while (cnt + a[j] + 1 <= w && j <= n) cnt += a[j++] + 1; f1[i][0] = j - i; } for (int j = 1; (1 << j) <= mx; j++) { for (int i = 1; i <= n; i++) { f1[i][j] = f1[i][j - 1] + f1[i + f1[i][j - 1]][j - 1]; } } for (int i = 1; i <= n; i++) { int cnt = 0, j = i, flag = 0; while (cnt + a[j] + flag <= dw) cnt += a[j++] + flag, flag = 1; int k = j; cnt = flag = 0; while (cnt + a[k] + flag <= w - pw - dw) cnt += a[k++] + flag, flag = 1; f2[i][0] = k - i; } for (int j = 1; (1 << j) <= mx; j++) { for (int i = 1; i <= n; i++) { if (f2[i][j - 1] == 0) f2[i][j] = 0; else f2[i][j] = f2[i][j - 1] + f2[i + f2[i][j - 1]][j - 1]; } }}int RMQ1(int i, int x) { if (x == 0) return i; while (x && i <= n) { int j = 0; while ((1 << (j + 1)) <= x) j++; i += f1[i][j]; x -= (1 << j); } return i;}int RMQ2(int i, int x) { if (x == 0) return i; while (x && i <= n) { int j = 0; while ((1 << (j + 1)) <= x) j++; i += f2[i][j]; x -= (1 << j); } return i;}int RMQ3(int i) { int ret = 0; while (i <= n) { int j = 0; while (i + f1[i][j + 1] <= n) j++; i += f1[i][j]; ret += (1 << j); } return ret;}struct Query { int x, h;} q[MX];int main() { //FIN; int T, m; scanf("%d", &T); while (T--) { scanf("%d%d%d%d", &n, &w, &pw, &dw); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); scanf("%d", &m); mx = n; for (int i = 1; i <= m; i++) scanf("%d%d", &q[i].x, &q[i].h), mx = max(mx, n + q[i].x + q[i].h); ST(); for (int i = 1; i <= m; i++) { int x = q[i].x, h = q[i].h; int tmp = RMQ3(1); if (tmp <= x - 1) { printf("%d\n", tmp + h); continue; } int ans = x + h - 1; int p = RMQ1(1, x - 1); p = RMQ2(p, h); if (p <= n) ans += RMQ3(p); printf("%d\n", ans); } } return 0;}
阅读全文
0 0
- HDU-6107 Typesetting(倍增法)
- HDU 6107 Typesetting(倍增法 17多校第六场)
- HDU 6107 Typesetting(ST)
- [HDU 5726] GCD (倍增法+二分)
- HDU 5875 Function(单调栈+在线倍增法)
- HDU 2586 How far away(倍增法)
- HDU-2874 Connections between cities(倍增法)
- hdu 4549 CD操作(lca倍增法)
- hdu 4674 (缩点 + 倍增LCA)
- HDU 6115 Factory(在线倍增LCA)
- 后缀数组(倍增法)
- HDU 6109 数据分割(并查集+set+在线倍增法)
- HDU 4547 倍增LCA
- HDU 4343 贪心+倍增
- HDU 5726 GCD 倍增
- Typesetting Engine_Trident
- Typesetting Engine_Gecko
- Typesetting Engine_KHTML
- 3.基础知识Android_ArrayMap
- 一个程序猿的工作感悟
- SMO算法
- Linux开发环境搭建01---VMware 12 Pro 虚拟机安装步骤详解
- 【C语言】【unix c】变量和常量
- HDU-6107 Typesetting(倍增法)
- STL总结(不定期更新...)
- 欢迎使用CSDN-markdown编辑器
- 动态代理模式分析
- 创建Zigbee Z-Stack 3.0.1 BSP(一)--概述
- 多进程模块multiprocessing
- storm 架构与原理
- 《ECMAScript 6入门》笔记4
- ffmpeg的编译选项浅析