HDU-3397-Sequence operation
来源:互联网 发布:mba有用吗 知乎 编辑:程序博客网 时间:2024/05/18 01:36
ACM模版
描述
题解
这道题涉及到的操作有五种,所以处理起来也有些复杂,最起码对于我这种渣来说,是复杂。
对于只有0和1的序列,让我想起来了以前碰见的一个扑克翻面的问题,不过是将0、1替换掉了正反面而已,当然,这个扑克翻面问题只有这个区间染色问题,没有这道题操作这么多,记得不错的话,那是道谷歌面试题……
这里涉及的五种操作分别是:
0:将区间所有值覆盖为0
1:将区间所有值覆盖为1
2:将区间所有值翻转(0和1交换)
3:求区间中所有1的个数
4:求区间中连续最长的1的个数
前两个实际上可以视为一种操作,而2操作实际上是一个异或操作,3是一般的区间操作,我也不知道怎么形容比较合适,4呢,让我想起来前两天做到的一个区间合并问题,求的是区间最长连续递增子序列长度,也就是说这道题是招组合拳,需要见招拆招,一招一招拆,还得考虑到招招之间的关系。
哎,我没事你跟你们瞎掰扯武侠那套了~~~原谅我是金庸迷!
这道题我也不是自己死磕出来的,刚开始做线段树专题训练,好多技巧都不熟(实际上是不会),所以参考了一些大牛们的代码,由于不只是看了一篇大牛们的题解,所以我就不引述了,百度一下,你就知道~~~
代码
#include <iostream>#include <cstdio>#define lson u << 1#define rson u << 1 | 1using namespace std;const int MAXN = 100010;int dat[MAXN];struct node{ int left, right; int lo, ro, mo; // 1:左端点为起点最长连续数目,右端点为终点最长连续数目,区间最长连续数目 int lz, rz, mz; // 0:左端点为起点最长连续数目,右端点为终点最长连续数目,区间最长连续数目 int res; // 区间1的个数 int COVER, XOR;} T[MAXN << 2];void makeXOR(int u){ // 翻转操作 swap(T[u].lo, T[u].lz); swap(T[u].ro, T[u].rz); swap(T[u].mo, T[u].mz); T[u].res = T[u].right - T[u].left + 1 - T[u].res;}void PushUp(int u){ if (T[u].left == T[u].right) { return ; } int len = T[u].right - T[u].left + 1; T[u].lo = T[lson].lo; T[u].ro = T[rson].ro; if (T[u].lo == (len + 1) >> 1) { T[u].lo += T[rson].lo; } if (T[u].ro == len >> 1) { T[u].ro += T[lson].ro; } T[u].mo = max(T[lson].mo, T[rson].mo); T[u].mo = max(T[u].mo, T[lson].ro + T[rson].lo); T[u].lz = T[lson].lz; T[u].rz = T[rson].rz; if (T[u].lz == (len + 1) >> 1) { T[u].lz += T[rson].lz; } if (T[u].rz == len >> 1) { T[u].rz += T[lson].rz; } T[u].mz = max(T[lson].mz, T[rson].mz); T[u].mz = max(T[u].mz, T[lson].rz + T[rson].lz); T[u].res = T[lson].res + T[rson].res;}void PushDown(int u){ if (T[u].left == T[u].right) { return ; } if (T[u].COVER != -1) { int len = T[u].right - T[u].left + 1; T[lson].COVER = T[rson].COVER = T[u].COVER; T[lson].XOR = T[rson].XOR = 0; T[lson].lo = T[lson].ro = T[lson].mo = T[u].COVER ? (len + 1) >> 1 : 0; T[lson].lz = T[lson].rz = T[lson].mz = T[u].COVER ? 0 : (len + 1) >> 1; T[lson].res = T[u].COVER ? (len + 1) >> 1 : 0; T[rson].lo = T[rson].ro = T[rson].mo = T[u].COVER ? len >> 1 : 0; T[rson].lz = T[rson].rz = T[rson].mz = T[u].COVER ? 0 : len >> 1; T[rson].res = T[u].COVER ? len >> 1 : 0; T[u].COVER = -1; } if (T[u].XOR) { T[u].XOR = 0; T[lson].XOR ^= 1; T[rson].XOR ^= 1; makeXOR(lson); makeXOR(rson); }}void Build(int u, int l, int r){ T[u].left = l; T[u].right = r; T[u].COVER = -1; T[u].XOR = 0; if (l == r) { T[u].lo = T[u].ro = T[u].mo = (dat[l] == 1); T[u].lz = T[u].rz = T[u].mz = (dat[l] == 0); T[u].res = dat[l]; T[u].COVER = dat[l]; return ; } int mid = (l + r) >> 1; Build(lson, l, mid); Build(rson, mid + 1, r); PushUp(u);}void Update(int u, int l, int r, int op){ PushDown(u); if (l <= T[u].left && T[u].right <= r) { if (op < 2) { // 覆盖操作 int len = T[u].right - T[u].left + 1; T[u].COVER = op; T[u].lo = T[u].ro = T[u].mo = op ? len : 0; T[u].lz = T[u].rz = T[u].mz = op ? 0 : len; T[u].res = op ? len : 0; } else { T[u].XOR = 1; makeXOR(u); } } else { if (l <= T[lson].right) { Update(lson, l, r, op); } if (r >= T[rson].left) { Update(rson, l, r, op); } PushUp(u); }}int Query(int u, int l, int r, int op){ PushDown(u); if (l <= T[u].left && T[u].right <= r) { if (op == 3) { return T[u].res; } else { return T[u].mo; } } else { if (r <= T[lson].right) { return Query(lson, l, r, op); } if (l >= T[rson].left) { return Query(rson, l, r, op); } if (op == 3) { return Query(lson, l, T[lson].right, op) + Query(rson, T[rson].left, r, op); } int ret = min(T[lson].ro, T[lson].right - l + 1) + min(T[rson].lo, r - T[rson].left + 1); int ans = max(Query(lson, l, T[lson].right, op), Query(rson, T[rson].left, r, op)); return max(ans, ret); }}int main(){ int t; scanf("%d", &t); while (t--) { int n, m; int cmd, a, b; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", dat + i); } Build(1, 1, n); while (m--) { scanf("%d%d%d", &cmd, &a, &b); a++, b++; if (cmd < 3) { Update(1, a, b, cmd); } else { printf("%d\n", Query(1, a, b, cmd)); } } } return 0;}
1 0
- HDU 3397 Sequence operation
- hdu 3397 Sequence operation
- HDU 3397 Sequence operation
- HDU-3397-Sequence operation
- hdu 3397 Sequence operation
- HDU 3397 Sequence operation
- HDU 3397 Sequence operation
- HDU 3397 Sequence operation
- hdu 3397 Sequence operation
- HDU 3397 Sequence operation
- HDU 3397 Sequence Operation
- HDU-3397-Sequence operation
- HDU 3397 Sequence operation
- HDU-3397 Sequence operation
- HDU 3397 Sequence operation
- HDU 3397 Sequence operation
- hdu 3397 Sequence operation
- HDU 3397 Sequence operation
- Java常用单词
- 计算题 (sdut oj)
- 高中数学? (sdut oj)
- 微信小程序维护登录态与获取用户信息_0
- eclipse从SVN检出maven web项目
- HDU-3397-Sequence operation
- Linux相关文章索引(3)
- 计算组合数 (sdut oj)
- 快速理解 FastCGI、PHP-CGI、PHP-FPM
- 1069.The Black Hole of Numbers (20)
- graph Laplacian 拉普拉斯矩阵
- 感知机
- 补间动画调用了VIEW哪些函数?
- 我为什么不看好微信小程序