点击打开链接

写了好久 终于AC 还是对线段树理解不到位

0 1操作是裸区间着色 2操作是裸区间翻转(异或) 对于这两种区间操作各设两个laz变量

3操作是裸区间查询 4操作略有技巧 可以先做一下hdu3911 来弄明白4操作

这题关键是处理好着色与翻转的先后顺序关系 举个例子:

设区间 [0,4] 为 1 1 0 1 1 有两个操作 a: 0 0 4 和 b: 2 0 4

先a后b得 1 1 1 1 1 先b后a得 0 0 0 0 0 结果截然相反

思路 如果某一个区间上只有一种标记 正常pushdown即可 但如果两者都有 必须保证着色优先级更高

1 若先有着色后有翻转 则执行完着色 再执行翻转

2 若先有翻转后有着色 则放弃执行翻转 直接执行着色

但是怎么实现呢? 难道开个变量记录先后次序? 如下:

在给某区间打着色标记后移除翻转标记 打翻转标记则不用管着色标记 这样就体现了先后顺序

pushdown时也是一样操作 先看该区间有没有着色标记 有的话向下打给子区间 同时移除子区间的翻转标记

如果该区间还有翻转标记 向下打给子区间即可

#include <bits/stdc++.h>
using namespace std;struct node
{int l;int r;int val;int left0;int right0;int all0;int left1;int right1;int all1;int laz1;int laz2;
};node tree[400010];
int n;void changeI(int cur,int val)
{if(val){tree[cur].val=tree[cur].r-tree[cur].l+1;tree[cur].left0=tree[cur].right0=tree[cur].all0=0;tree[cur].left1=tree[cur].right1=tree[cur].all1=tree[cur].r-tree[cur].l+1;}else{tree[cur].val=0;tree[cur].left0=tree[cur].right0=tree[cur].all0=tree[cur].r-tree[cur].l+1;tree[cur].left1=tree[cur].right1=tree[cur].all1=0;}return;
}void changeII(int cur)
{swap(tree[cur].left0,tree[cur].left1);swap(tree[cur].right0,tree[cur].right1);swap(tree[cur].all0,tree[cur].all1);tree[cur].val=(tree[cur].r-tree[cur].l+1)-tree[cur].val;return;
}void pushup(int cur)
{tree[cur].val=tree[2*cur].val+tree[2*cur+1].val;tree[cur].left0=tree[2*cur].left0;if(tree[cur].left0==tree[2*cur].r-tree[2*cur].l+1) tree[cur].left0+=tree[2*cur+1].left0;tree[cur].right0=tree[2*cur+1].right0;if(tree[cur].right0==tree[2*cur+1].r-tree[2*cur+1].l+1) tree[cur].right0+=tree[2*cur].right0;tree[cur].all0=max(tree[2*cur].right0+tree[2*cur+1].left0,max(tree[2*cur].all0,tree[2*cur+1].all0));tree[cur].left1=tree[2*cur].left1;if(tree[cur].left1==tree[2*cur].r-tree[2*cur].l+1) tree[cur].left1+=tree[2*cur+1].left1;tree[cur].right1=tree[2*cur+1].right1;if(tree[cur].right1==tree[2*cur+1].r-tree[2*cur+1].l+1) tree[cur].right1+=tree[2*cur].right1;tree[cur].all1=max(tree[2*cur].right1+tree[2*cur+1].left1,max(tree[2*cur].all1,tree[2*cur+1].all1));return;
}void pushdown(int cur)
{if(tree[cur].laz1!=-1){changeI(2*cur,tree[cur].laz1);tree[2*cur].laz1=tree[cur].laz1;tree[2*cur].laz2=0;changeI(2*cur+1,tree[cur].laz1);tree[2*cur+1].laz1=tree[cur].laz1;tree[2*cur+1].laz2=0;tree[cur].laz1=-1;}if(tree[cur].laz2!=0){changeII(2*cur);tree[2*cur].laz2^=1;changeII(2*cur+1);tree[2*cur+1].laz2^=1;tree[cur].laz2=0;}return;
}void build(int l,int r,int cur)
{int m,t;tree[cur].l=l;tree[cur].r=r;tree[cur].laz1=-1;tree[cur].laz2=0;if(l==r){scanf("%d",&t);if(t){tree[cur].val=1;tree[cur].left0=tree[cur].right0=tree[cur].all0=0;tree[cur].left1=tree[cur].right1=tree[cur].all1=1;}else{tree[cur].val=0;tree[cur].left0=tree[cur].right0=tree[cur].all0=1;tree[cur].left1=tree[cur].right1=tree[cur].all1=0;}return;}m=(l+r)/2;build(l,m,2*cur);build(m+1,r,2*cur+1);pushup(cur);return;
}void updateI(int pl,int pr,int val,int cur)
{if(pl<=tree[cur].l&&tree[cur].r<=pr){changeI(cur,val);tree[cur].laz1=val;tree[cur].laz2=0;return;}pushdown(cur);if(pl<=tree[2*cur].r) updateI(pl,pr,val,2*cur);if(pr>=tree[2*cur+1].l) updateI(pl,pr,val,2*cur+1);pushup(cur);return;
}void updateII(int pl,int pr,int cur)
{if(pl<=tree[cur].l&&tree[cur].r<=pr){changeII(cur);tree[cur].laz2^=1;return;}pushdown(cur);if(pl<=tree[2*cur].r) updateII(pl,pr,2*cur);if(pr>=tree[2*cur+1].l) updateII(pl,pr,2*cur+1);pushup(cur);return;
}int queryI(int pl,int pr,int cur)
{int res;if(pl<=tree[cur].l&&tree[cur].r<=pr){return tree[cur].val;}pushdown(cur);res=0;if(pl<=tree[2*cur].r) res+=queryI(pl,pr,2*cur);if(pr>=tree[2*cur+1].l) res+=queryI(pl,pr,2*cur+1);return res;
}int queryII(int pl,int pr,int cur)
{int tl,tr,tm;if(pl<=tree[cur].l&&tree[cur].r<=pr){return tree[cur].all1;}pushdown(cur);if(pr<=tree[2*cur].r) return queryII(pl,pr,2*cur);else if(pl>=tree[2*cur+1].l) return queryII(pl,pr,2*cur+1);else{tl=queryII(pl,pr,2*cur),tr=queryII(pl,pr,2*cur+1);tm=min(tree[2*cur].r-pl+1,tree[2*cur].right1)+min(pr-tree[2*cur+1].l+1,tree[2*cur+1].left1);return max(tm,max(tl,tr));}
}int main()
{int t,q,op,l,r;scanf("%d",&t);while(t--){scanf("%d%d",&n,&q);build(0,n-1,1);while(q--){scanf("%d%d%d",&op,&l,&r);if(op==0){updateI(l,r,0,1);}else if(op==1){updateI(l,r,1,1);}else if(op==2){updateII(l,r,1);}else if(op==3){printf("%d\n",queryI(l,r,1));}else{printf("%d\n",queryII(l,r,1));}}}return 0;
}

Sequence operation HDU - 3397相关推荐

  1. 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变 ...

  2. hdu 3397 Sequence operation(线段树,lazy,区间合并)

    hdu 3397 Sequence operation 线段树lazy和区间合并结合的一个题,相当于几个题集中到一起嘛,分开想就好了 0,1,2操作都要lazy,2的异或操作找到每一只含1或只含0的区 ...

  3. HDU 3397 Sequence operation 线段树 成段更新 区间合并

    比较综合的题. 两个标记  setv,xorr.setv的优先级高于xorr,当一个节点获得一个setv时,他之前的xorr要清除. //#pragma comment(linker, "/ ...

  4. HDU 3397 Sequence operation

    裸线段树区间合并,题目本身不难,就是细节处理比较麻烦. 因为涉及到异或运算,所以连续0和连续1的个数都要记录一下. 操作的懒惰标记我只用了一个flag,注意flag更新时的细节,我分了三种情况: fl ...

  5. HDU - 3397 Sequence operation(线段树+区间合并)

    题目链接:点击查看 题目大意:给定一个初始的数列,然后依次进行m次操作: 0 a b:将闭区间[a,b]内的点都变为0 1 a b:将闭区间[a,b]内的点都变为1 2 a b:将闭区间[a,b]内的 ...

  6. 【线段树】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 ...

  7. HDU 3397 Sequence operation(线段树区间合并)

    题意: 0 a b将区间[a,b]所有数全部变成0 1 a b将区间[a,b]所有数全部变成1 2 a b将区间[a,b]中所有数0 1互换,0变1,1变0 3 a b输出区间[a,b]中1的个数 4 ...

  8. Sequence II HDU - 5919(主席树)

    Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,⋯,ana1,a2,⋯,an There are ...

  9. Sequence II (HDU 5919)(主席树)

    Sequence II 题目大意是有mmm次询问,每次询问一段区间[l,r][l, r][l,r],从左到右,如果这个数是在这个区间第一次出现,则记录下其下标, 我们会得到一个新的数组,要求这个数组的 ...

最新文章

  1. CentOS 7下源码编译安装新版本内核
  2. 【数据平台】Eclipse+MapReduce开发环境(集群运行模式)
  3. 变分自编码器VAE:一步到位的聚类方案
  4. 单片机定时器实验两位倒计时秒表_单片机学习「1」 初始51单片机
  5. 【poj2114】点分治(离线)
  6. 详解T-SQL的联接机制
  7. 软件测试几个概念 --dev sit uat
  8. 更新计算机上的windows模块安装程序_Win10中用DOS命令也可以完成windows更新,这个技巧还真不知道...
  9. Nginx完美解决前后端分离端口号不同导致的跨域问题
  10. 制作Windows 10系统盘 全过程『手机版』
  11. html小说站源码,读取本地HTML的小说阅读器应用源码项目
  12. 废弃台式计算机类别,废旧台式电脑(台式机)属于什么垃圾分类?
  13. uni.navigateTo传参
  14. 给“四时有惑”播客招募几位志愿者
  15. 不经意传输协议-密码学
  16. 天美生物在美上市背后:财务报表存在重大缺陷,胡永卫持股34%
  17. c语言中被3除 余数为2,五年级奥数题:带余数除法(B)
  18. React中如何引入css呢
  19. 体虚分为气虚、血虚、阴虚、阳虚四种类型
  20. 《班扎古鲁白玛的沉默》

热门文章

  1. 模拟cmos集成电路(6)
  2. MySQL定时任务(每天0点自动执行)
  3. 三体船的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  4. 行人重识别论文阅读(2021.7.3-7.11)
  5. 调大图片内存大小和降低图片内存大小快过来
  6. 09-word不显示段落标记(去掉回车符号)取消拼写错误
  7. Python小姿势 - Python爬取网页数据
  8. ...this.props
  9. STM32C8T6 学习总结+资料分享
  10. java+ jsp+js 实现富文本编辑和上传图片功能