计蒜客 - 黑白石头
沙滩上有一些石头,石头的颜色是白色或者黑色。小羊会魔法,它能把连续一段的石头,黑色变成白色,白色变成黑色。小羊喜欢黑色,她想知道某些区间中最长的连续黑石头是多少个。
输入格式
第一行一个整数 n ( 1 ≤ n ≤ 100000 ) n(1\leq n\leq 100000) n(1≤n≤100000)。
第二行 n n n 个整数,表示石头的颜色, 0 0 0 是白色, 1 1 1 是黑色。
第三行一个整数 m ( 1 ≤ m ≤ 100000 ) m(1\leq m\leq 100000) m(1≤m≤100000)。
接下来 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