现在的位置: 首页 > 综合 > 正文

HDU 3397 Sequence operation(线段…

2018年03月17日 ⁄ 综合 ⁄ 共 1729字 ⁄ 字号 评论关闭
题意:给个一只有0,1 的序列,有以下5种操作
0 a b change all characters into '0's in [a , b] //把a,b间的都改为0
1 a b change all characters into '1's in [a , b] //把a,b间都改为1
2 a b change all '0's into '1's and change all '1's into '0's in
[a, b] //1的改为0,0的改为1
Output operations:
3 a b output the number of '1's in [a, b]  //a,b间1
的数量
4 a b output the length of the longest continuous '1' string in [a
, b]//a,b间最大连续的1的个数

思路:经典的线段树,只是操作过多,但其实很简单,相当于把以前做过的题的操作合在一块 什么值的更改,区间和的查询,最开连续的个数
。所以没什么特殊的

//1312MS   
8836K
#include <stdio.h>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define M 100010

struct tree
{
    int
l,r,len;  //len 是该区间的长度
    int
sum,cover;   //sum 是该区间1的数量,cover
有3个值-1,0,1分别表示该区间是否被0,1完全覆盖
    int
lm,rm,ma;   
//lm rm ma 分别表示 左连续 右连续 和最大的连续1的个数
} node[M*4];

int num[M];

int max (int a,int b)
{
    return a
> b ? a : b;
}
int min (int a ,int b)
{
    return a
> b ? b : a;
}
void Union (int u)  //区间合并,由子结点修改父结点的信息
                   
//常用手法 就不多解释了
    node[u].sum
= node[L(u)].sum + node[R(u)].sum;
    if
(node[L(u)].len == node[L(u)].lm)
       
node[u].lm = node[L(u)].len + node[R(u)].lm;
    else
       
node[u].lm = node[L(u)].lm;
    if
(node[R(u)].len == node[R(u)].rm)
       
node[u].rm = node[R(u)].len + node[L(u)].rm;
    else
       
node[u].rm = node[R(u)].rm;
    int a = max
(node[L(u)].ma,node[R(u)].ma);
    int b = max
(node[u].lm,node[u].rm);
    node[u].ma =
max (max (a,b),node[L(u)].rm + node[R(u)].lm);
}
void Build (int u,int left,int right)
{
    node[u].l =
left;
    node[u].r =
right;
    node[u].len
= right - left + 1;
   
node[u].cover = -1;
    if (left ==
right)
    {
       
if (num[left])
       
{
           
node[u].sum = 1;
           
node[u].cover = 1;
           
node[u].lm = node[u].rm = node[u].ma = 1;
       
}
       
else
       
{
           
node[u].sum = 0;
           
node[u].cover = 0;
           
node[u].lm = node[u].rm = node[u].ma = 0;
       
}
       
return ;
    }
    int mid =
(left + right)>>1;
    Build
(L(u),left,mid);
    Build
(R(u),mid+1,right);
    Union
(u);
}
void getdown (int
u)   

抱歉!评论已关闭.