hdu3397 Sequence operation

 #include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+;
struct node {
/// l,r表示当前结点区间范围[l,r]
int l, r;
/// val=0时为全0标志,表示区间[l,r]的值全为0
/// val=1时为全1标志,表示区间[l,r]的值全为1
/// val=-1时则代表无操作
/// xor为异或标志,表示区间[l,r]的值取异或操作
int val, Xor;
/// lmax_0表示区间[l,r]从左往右开始连续0的个数
/// rmax_0表示区间[l,r]从右往左开始连续0的个数
/// max_0表示当前区间最大连续0的个数
int lmax_0, rmax_0, max_0, sum_0;
int lmax_1, rmax_1, max_1, sum_1;
/// 得到当前区间长度
int len() { return r-l+; } /// 更新操作,val_代表01操作,xor_代表异或操作
void change(int val_, int Xor_) {
/// [l,r]全置为0
if (val_ == ) {
lmax_0 = rmax_0 = max_0 = sum_0 = len();
lmax_1 = rmax_1 = max_1 = sum_1 = ;
val = , Xor = ;
}
/// [l,r]全置为1
else if (val_ == ) {
lmax_0 = rmax_0 = max_0 = sum_0 = ;
lmax_1 = rmax_1 = max_1 = sum_1 = len();
val = , Xor = ;
}
/// [l,r]全异或
if (Xor_ == ) {
swap(lmax_0,lmax_1); swap(rmax_0,rmax_1);
swap(max_0,max_1); swap(sum_0,sum_1);
Xor ^= ;
}
}
}tree[maxn*];
int a[maxn];
void pushup(node &fa, node &ls, node &rs) {
/// 父节点的左边最长0串=左子树的左边最长0串
fa.lmax_0 = ls.lmax_0, fa.rmax_0 = rs.rmax_0;
fa.lmax_1 = ls.lmax_1, fa.rmax_1 = rs.rmax_1;
/// 父节点0的数量=左子树0的数量+右子树0的数量
fa.sum_0 = ls.sum_0+rs.sum_0;
fa.sum_1 = ls.sum_1+rs.sum_1;
/// 父节点最大连续0串等于左右子树里面中最大连续0串的最大值
/// 或者是左子树从右开始的0串+右子树从左开始的0串之和
fa.max_0 = max(max(ls.max_0,rs.max_0), ls.rmax_0+rs.lmax_0);
fa.max_1 = max(max(ls.max_1,rs.max_1), ls.rmax_1+rs.lmax_1); /// 如果左子树整串都为0串
if (ls.len() == ls.lmax_0) fa.lmax_0 += rs.lmax_0;
if (ls.len() == ls.lmax_1) fa.lmax_1 += rs.lmax_1;
if (rs.len() == rs.rmax_0) fa.rmax_0 += ls.rmax_0;
if (rs.len() == rs.rmax_1) fa.rmax_1 += ls.rmax_1;
}
void pushdown(int rt) {
if (tree[rt].val != - || tree[rt].Xor) {
tree[rt*].change(tree[rt].val,tree[rt].Xor);
tree[rt*+].change(tree[rt].val,tree[rt].Xor);
tree[rt].val = -, tree[rt].Xor = ;
}
}
void build(int rt, int l, int r) {
/// 结点初始化
tree[rt].l = l, tree[rt].r = r;
tree[rt].lmax_0 = tree[rt].rmax_0 = ;
tree[rt].lmax_1 = tree[rt].rmax_1 = ;
tree[rt].max_0 = tree[rt].max_1 = ;
tree[rt].sum_0 = tree[rt].sum_1 = ;
tree[rt].Xor = , tree[rt].val = -;
/// 如果是叶子结点
if (l == r) {
tree[rt].change(a[l],);
return;
}
int mid = (l+r)/;
build(rt*,l,mid);
build(rt*+,mid+,r);
pushup(tree[rt],tree[rt*],tree[rt*+]);
}
void update(int rt, int l, int r, int op) {
int L = tree[rt].l, R = tree[rt].r;
if (l <= L && R <= r) {
/// 根据op执行不同操作
if (op == || op == ) tree[rt].change(op,);
else if (op == ) tree[rt].change(-,);
return;
}
pushdown(rt);
int mid = (L+R)/;
if (mid >= l) update(rt*,l,r,op);
if (mid < r) update(rt*+,l,r,op);
pushup(tree[rt],tree[rt*],tree[rt*+]);
}
int query(int rt, int l, int r, int op) {
int L = tree[rt].l, R = tree[rt].r;
if (l <= L && R <= r) {
if (op == ) return tree[rt].sum_1;
else if (op == ) return tree[rt].max_1;
}
int mid = (L+R)/;
pushdown(rt);
if (r <= mid) return query(rt*,l,r,op);
else if (l > mid) return query(rt*+,l,r,op);
else {
int max1 = query(rt*,l,r,op);
int max2 = query(rt*+,l,r,op);
if (op == ) return max1+max2;
int max3 = min(tree[rt*].r-l+,tree[rt*].rmax_1)+min(r-tree[rt*+].l+,tree[rt*+].lmax_1);
return max(max(max1,max2),max3);
}
}
int main() {
int t; scanf("%d",&t);
while (t--) {
int n, m; scanf("%d%d",&n,&m);
for (int i = ; i < n; ++i)
scanf("%d",&a[i]);
build(,,n-);
while (m--) {
int op, a, b;
scanf("%d%d%d",&op,&a,&b);
if (op == || op == || op == ) update(,a,b,op);
else printf("%d\n",query(,a,b,op));
}
}
return ;
}

最新文章

  1. 在powerdesigner中创建物理数据模型
  2. Redis教程(十二):服务器管理命令总结
  3. css3 弹框功能样式
  4. 查看linux库文件32位还是64位
  5. jquery事件切换hover/toggle
  6. 使用 Microsoft Word 发布博客文章
  7. ios ReactiveViewModel
  8. Linux TCP/IP parameters reference
  9. hibernate 一张数据表的流程
  10. iOS:编译错误Undefined symbols for architecture i386: _OBJC_CLASS_$_XXX&amp;quot;, referenced from: error
  11. LinkButton和HyperLink的页面跳转用法
  12. 【原创】纯OO:从设计到编码写一个FlappyBird (三)
  13. nginx配置错误
  14. Linux以字节显示内存大小
  15. JavaScript头像上传器的实现
  16. ACM-ICPC 2018 焦作赛区网络预赛 G. Give Candies (打表找规律+快速幂)
  17. sjw-风评评测-定位页面元素
  18. 使用/\_ 打印正三角形 C/C++
  19. .Net-C#异步程序知识点梳理
  20. j2ee model1模型完成分页逻辑的实现 详解!

热门文章

  1. 8、Flink Table API &amp; Flink Sql API
  2. PHP中级篇 Apache配置httpd-vhosts虚拟主机总结及注意事项
  3. Nmap详细用法
  4. python学习03字符串基本操作
  5. Scala教程之:Future和Promise
  6. 实现QQ内打开链接跳转至浏览器
  7. 正则表达式(grep,awk,sed)和通配符
  8. React Native中自定义导航条
  9. “Too many texture interpolators would be used for ForwardBase pass”
  10. Uber是一部无所不在的数字出行物联网