【HDOJ】3397 Sequence operation
线段树的应用,很不错的一道题目。结点属性包括:
(1)n1:1的个数;
(2)c1:连续1的最大个数;
(3)c0:连续0的最大个数;
(4)lc1/lc0:从区间左边开始,连续1/0的最大个数;
(5)rc1/rc0:从区间右边开始,连续1/0的最大个数;
(6)set:置区间为0/1的标记;
(7)flip:0->1, 1->0的标记。
采用延迟更新。每当更新set时,flip就置为false;每当更新flip时,其实就是c1/c0, lc1/lc0, rc1/rc0的交换。
对于询问最长连续1,共包括3种情况:左子树的最长连续1,右子树的最长连续1,以及左子树rc1+右子树lc1(注意有效范围区间)。
- /* 3397 */
- #include <iostream>
- #include <string>
- #include <map>
- #include <queue>
- #include <set>
- #include <vector>
- #include <algorithm>
- #include <cstdio>
- #include <cmath>
- #include <cstring>
- #include <climits>
- #include <cctype>
- using namespace std;
- #define MAXN 100005
- #define lson l, mid, rt<<1
- #define rson mid+1, r, rt<<1|1
- typedef struct {
- int set;
- int n1;
- int c1, c0;
- int lc1, lc0, rc1, rc0;
- bool flip;
- } node_t;
- node_t nd[MAXN<<];
- int t, n, m, x;
- int op;
- void maintance_set(int op, int len, int rt) {
- nd[rt].set = op;
- nd[rt].flip = false;
- if (op) {
- nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = len;
- nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = ;
- } else {
- nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = ;
- nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = len;
- }
- }
- void maintance_flip(int len, int rt) {
- if (nd[rt].set >= )
- nd[rt].set = !nd[rt].set;
- else
- nd[rt].flip = !nd[rt].flip;
- nd[rt].n1 = len-nd[rt].n1;
- swap(nd[rt].c0, nd[rt].c1);
- swap(nd[rt].lc0, nd[rt].lc1);
- swap(nd[rt].rc0, nd[rt].rc1);
- }
- void PushUp(int l, int r, int rt) {
- int lb = rt<<;
- int rb = rt<<|;
- int mid = (l+r)>>;
- // update the number of 1
- nd[rt].n1 = nd[lb].n1 + nd[rb].n1;
- // update the longest continuous 1 and 0 in string
- nd[rt].c1 = max(
- max(nd[lb].c1, nd[rb].c1),
- nd[lb].rc1 + nd[rb].lc1
- );
- nd[rt].c0 = max(
- max(nd[lb].c0, nd[rb].c0),
- nd[lb].rc0 + nd[rb].lc0
- );
- // update the longest continuous 1/0 from left
- nd[rt].lc1 = nd[lb].lc1;
- nd[rt].lc0 = nd[lb].lc0;
- if (nd[lb].lc1 == mid-l+)
- nd[rt].lc1 += nd[rb].lc1;
- if (nd[lb].lc0 == mid-l+)
- nd[rt].lc0 += nd[rb].lc0;
- // update the longest continuous 1/0 from right
- nd[rt].rc1 = nd[rb].rc1;
- nd[rt].rc0 = nd[rb].rc0;
- if (nd[rb].rc1 == r-mid)
- nd[rt].rc1 += nd[lb].rc1;
- if (nd[rb].rc0 == r-mid)
- nd[rt].rc0 += nd[lb].rc0;
- }
- void PushDown(int l, int r, int rt) {
- int lb = rt<<;
- int rb = rt<<|;
- int mid = (l+r)>>;
- if (nd[rt].set >= ) {
- // maintance_set lson & rson
- maintance_set(nd[rt].set, mid-l+, lb);
- maintance_set(nd[rt].set, r-mid, rb);
- nd[rt].set = -;
- }
- if (nd[rt].flip) {
- // maintance_flip lson & rson
- maintance_flip(mid-l+, lb);
- maintance_flip(r-mid, rb);
- nd[rt].flip = false;
- }
- }
- void build(int l, int r, int rt) {
- nd[rt].set = -;
- nd[rt].flip = false;
- if (l == r) {
- scanf("%d", &x);
- nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = x;
- nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = !x;
- return ;
- }
- int mid = (l+r)>>;
- build(lson);
- build(rson);
- PushUp(l, r, rt);
- }
- // update to set [L, R] to op
- void update1(int L, int R, int l, int r, int rt) {
- if (L<=l && R>=r) {
- maintance_set(op, r-l+, rt);
- return ;
- }
- int mid = (l+r)>>;
- PushDown(l, r, rt);
- if (L <= mid)
- update1(L, R, lson);
- if (R > mid)
- update1(L, R, rson);
- PushUp(l, r, rt);
- }
- // update to flip [L, R] one
- void update2(int L, int R, int l, int r, int rt) {
- if (L<=l && R>=r) {
- maintance_flip(r-l+, rt);
- return ;
- }
- int mid = (l+r)>>;
- PushDown(l, r, rt);
- if (L <= mid)
- update2(L, R, lson);
- if (R > mid)
- update2(L, R, rson);
- PushUp(l, r, rt);
- }
- // query the sum of 1 in [L, R]
- int query3(int L, int R, int l, int r, int rt) {
- if (L<=l && R>=r)
- return nd[rt].n1;
- int mid = (l+r)>>;
- PushDown(l, r, rt);
- int ret = ;
- if (L <= mid)
- ret += query3(L, R, lson);
- if (R > mid)
- ret += query3(L, R, rson);
- return ret;
- }
- // query the longest continous 1 in [L, R]
- int query4(int L, int R, int l, int r, int rt) {
- if (L<=l && R>=r)
- return nd[rt].c1;
- int mid = (l+r)>>;
- PushDown(l, r, rt);
- int ret;
- if (L > mid) {
- return query4(L, R, rson);
- } else if (R <= mid) {
- return query4(L, R, lson);
- } else {
- ret = max(
- query4(L, R, lson),
- query4(L, R, rson)
- );
- int rc1 = nd[rt<<].rc1;
- int lc1 = nd[rt<<|].lc1;
- if (rc1 > mid-L+)
- rc1 = mid-L+;
- if (lc1 > R-mid)
- lc1 = R-mid;
- ret = max(
- rc1 + lc1,
- ret
- );
- }
- return ret;
- }
- int main() {
- int i, j, k;
- int a, b;
- #ifndef ONLINE_JUDGE
- freopen("data.in", "r", stdin);
- freopen("data.out", "w", stdout);
- #endif
- scanf("%d", &t);
- while (t--) {
- scanf("%d %d", &n, &m);
- build(, n, );
- while (m--) {
- scanf("%d %d %d", &op, &a, &b);
- ++a;
- ++b;
- if (op == ) {
- update1(a, b, , n, );
- } else if (op == ) {
- update1(a, b, , n, );
- } else if (op == ) {
- update2(a, b, , n, );
- } else if (op == ) {
- k = query3(a, b, , n, );
- printf("%d\n", k);
- } else {
- k = query4(a, b, , n, );
- printf("%d\n", k);
- }
- }
- }
- return ;
- }
【HDOJ】3397 Sequence operation的更多相关文章
- HDU 3397 Sequence operation(线段树)
HDU 3397 Sequence operation 题目链接 题意:给定一个01序列,有5种操作 0 a b [a.b]区间置为0 1 a b [a,b]区间置为1 2 a b [a,b]区间0变 ...
- 【arc071f】Infinite Sequence(动态规划)
[arc071f]Infinite Sequence(动态规划) 题面 atcoder 洛谷 题解 不难发现如果两个不为\(1\)的数连在一起,那么后面所有数都必须相等. 设\(f[i]\)表示\([ ...
- 【arc074e】RGB Sequence(动态规划)
[arc074e]RGB Sequence(动态规划) 题面 atcoder 洛谷 翻译见洛谷 题解 直接考虑暴力\(dp\),设\(f[i][j][k][l]\)表示当前考虑到第\(i\)位,最后一 ...
- 【BZOJ1367】[Baltic2004]sequence 左偏树
[BZOJ1367][Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sampl ...
- 【BZOJ3043】IncDec Sequence 乱搞
[BZOJ3043]IncDec Sequence Description 给定一个长度为n的数列{a1,a2...an},每次可以选择一个区间[l,r],使这个区间内的数都加一或者都减一.问至少需要 ...
- hdu 3397 Sequence operation(很有意思的线段树题)
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- 【HDOJ】5063 Operation the Sequence
#include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 100005 #defin ...
- 【线段树】HDU 3397 Sequence operation 区间合并
操作 Change operations: 0 a b change all characters into '0's in [a , b] 1 a b change all characters i ...
- 【HDOJ】2062 Subset sequence
这道题目非常好,饶了点儿圈子.我的思路是,先按照组排列.例如,1 2 31 2 2 1 3 11 2 3 2 1 3 ...
随机推荐
- JavaScript 开发规范要求详解
作为一名开发人员(We前端JavaScript开发),不规范的开发不仅使日后代码维护变的困难,同时也不利于团队的合作,通常还会带来代码安全以及执行效率上的问题.本人在开发工作中就曾与不按规范来开发的同 ...
- 关于jquery获取服务器端xml数据
其实这个很简单,但是有时候简单的东西会让你犯一些低级错误. 今天写了个spring mvc 的服务器端接口,主要是用来共享一些数据库数据. 请求字段:http://localhost:8080/XXX ...
- 【原创教程】鲸吞HTML
首先,我们的angularJS课程分为三大模块: HTML/CSS/JS基础. angularJS详解. angualrJS的一些实用框架讲解. 其中,第一大模块的对象是对前端开发技术有点了解但不熟悉 ...
- (转)spring ioc原理(看完后大家可以自己写一个spring)
最近,买了本Spring入门书:spring In Action .大致浏览了下感觉还不错.就是入门了点.Manning的书还是不错的,我虽然不像哪些只看Manning书的人那样专注于Manning, ...
- [Excel] CsvHelper---C#关于CSV文件的导入和导出以及转化 (转载)
点击下载 CsvHelper.rar 这个类是关于Csv文件的一些高级操作1.DataTable导出到CSV2.将Csv读入DataTable看下面代码吧 /// <summary> // ...
- 微信Demo导入遇到的问题
最近做支付宝和微信接入自己APP工程的功能,遇到了一些问题,跟大家分享: 这里先说Android开发微信支付接入. 首先根据官方文档进行,对比支付宝的官方文档,微信部分更显得“摘要”一些. 导入后自行 ...
- Android - 广播机制和Service
花了几天,想实现定位功能,使用的是百度的服务,有时真的很无奈,就是一小小个问题,就能折腾好几天. 首先,我是在主线程(Fragment)中单独进行定位,发现不起作用. 然后我想使用Service和广播 ...
- html-----005
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 类库探源——System.Exception
一.MSDN描述 Exception 类: 表示在应用程序执行期间发生的错误 命名空间 : System 程序集: mscorlib.dll 继承关系: 常用属性(含字段)和方法: 1. 属性Me ...
- cocos2d-x系列 Mac下配置cocos2d-x开发环境(android和ios)
一.下载cocos2d-x http://cocos2d-x.org/projects/cocos2d-x/wiki/Download cocos2d-x-2.1.4.zip @ June.18, 2 ...