计蒜客 - 黑白石头

计蒜客 - 黑白石头

沙滩上有一些石头,石头的颜色是白色或者黑色。小羊会魔法,它能把连续一段的石头,黑色变成白色,白色变成黑色。小羊喜欢黑色,她想知道某些区间中最长的连续黑石头是多少个。

输入格式

第一行一个整数 n ( 1 ≤ n ≤ 100000 ) n(1\leq n\leq 100000) n(1n100000)

第二行 n n n 个整数,表示石头的颜色, 0 0 0 是白色, 1 1 1 是黑色。

第三行一个整数 m ( 1 ≤ m ≤ 100000 ) m(1\leq m\leq 100000) m(1m100000)

接下来 m m m 行,每行三个整数 x , i , j x,i,j x,i,j

x = 1 x = 1 x=1 表示改变 [i,j] 石头的颜色。

x = 0 x = 0 x=0 表示询问 [i,j] 最长连续黑色石头的长度。

4
1 0 1 0
5
0 1 4
1 2 3
0 1 4
1 3 3
0 4 4

输出格式

x = 0 x = 0 x=0 时,输出答案。

1
2
0

这道题算比较难的了,主要是需要维护最左端和最右端的连续黑白石头个数。

private void pushUp(NODE node) throws Exception {
   
    NODE leftChild = getLeftChild(node);
    NODE rightChild = getRightChild(node);

    int tmp;

    // 左孩子
    // 左边黑色石头的长度
    tmp = leftChild.getCache(NODE.identifier.LEFT_BLACK);
    if (leftChild.getRange() == tmp) {
   
        // 如果左孩子全是黑的,就加上右孩子的左边黑色
        tmp += rightChild.getCache(NODE.identifier.LEFT_BLACK);
    }
    node.setCache(NODE.identifier.LEFT_BLACK, tmp);
    // 左边白色石头的长度
    tmp = leftChild.getCache(NODE.identifier.LEFT_WHITE);
    if (leftChild.getRange() == tmp) {
   
        tmp += rightChild.getCache(NODE.identifier.LEFT_WHITE);
    }
    node.setCache(NODE.identifier.LEFT_WHITE, tmp);

    // 右孩子
    // 右边黑色石头的长度
    tmp = rightChild.getCache(NODE.identifier.RIGHT_BLACK);
    if (rightChild.getRange() == tmp) {
   
        // 如果左孩子全是黑的,就加上右孩子的左边黑色
        tmp += leftChild.getCache(NODE.identifier.RIGHT_BLACK);
    }
    node.setCache(NODE.identifier.RIGHT_BLACK, tmp);
    // 白色石头的长度
    tmp = rightChild.getCache(NODE.identifier.RIGHT_WHITE);
    if (rightChild.getRange() == tmp) {
   
        tmp += leftChild.getCache(NODE.identifier.RIGHT_WHITE);
    }
    node.setCache(NODE.identifier.RIGHT_WHITE, tmp);

    // 取最大的,要么是左孩子最大的,要么是右孩子最大的,要么是跨越左右的
    tmp = Math.max(leftChild.getCache(NODE.identifier.MAX_BLACK), rightChild.getCache(NODE.identifier.MAX_BLACK));
    tmp = Math.max(tmp, leftChild.getCache(NODE.identifier.RIGHT_BLACK) + rightChild.getCache(NODE.identifier.LEFT_BLACK));
    node.setCache(NODE.identifier.MAX_BLACK, tmp);
    tmp = Math.max
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凝神长老

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值