hdu 3397 线段树前后缀blahblah Sequence operation
来源:互联网 发布:算法工程师要求 编辑:程序博客网 时间:2024/06/05 15:21
题意:
给出一个长度为N(N <= 100000)的数列,然后是五种操作:
插入操作:
0 a b 将所有[a, b]区间内的数改成0
1 a b 将所有[a, b]区间内的数改成1
2 a b 将所有[a, b]区间内的数异或一下(0边1,1变0)
输出操作:
3 a b 输出[a, b]区间内1的数量
给出一个长度为N(N <= 100000)的数列,然后是五种操作:
插入操作:
0 a b 将所有[a, b]区间内的数改成0
1 a b 将所有[a, b]区间内的数改成1
2 a b 将所有[a, b]区间内的数异或一下(0边1,1变0)
输出操作:
3 a b 输出[a, b]区间内1的数量
4 a b 输出[a, b]区间内最长的连续1串
解:
正解应该比较简单。然而我的解就有点Orz了。 每个节点信息是:
preb, prew,sufb,sufw,mxb,mxw,sumb,sumw,Xor 这么多。
其他几个就不用说了,sumb是记录这个区间有多少1,Xor是lazy标志(之前没有这个,果断wa了)。 然后就写得。。。不过还好,push_up没写错呵呵。。。
后续:
简单的解法就是只维护一个cov就行了。cov = 1/0,表示这个区间全是1或者全是0,cov = -1表示有多种值。Orz。。。。
/*Pro: 0Sol:date:*/#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <set>#include <vector>#define maxn 100010#define ls rt << 1#define rs rt << 1 | 1#define havem int m =(l + r) >> 1#define lson l,m , rt << 1#define rson m + 1 , r, rt << 1 | 1using namespace std;int preb[maxn << 2], sufb[maxn << 2], prew[maxn << 2], sufw[maxn << 2], mxb[maxn << 2], mxw[maxn << 2];int sumb[maxn << 2],sumw[maxn << 2], Xor[maxn << 2];int n,T,Q,tmp,op,a,b;inline int max(int a, int b, int c){ return ( (a > b) ? ( (a > c) ? a: c) : ( (b > c) ? b : c) );}void push_up(int rt, int m){ sumb[rt] = sumb[ls] + sumb[rs]; sumw[rt] = sumw[ls] + sumw[rs]; preb[rt] = preb[ls]; if(preb[ls] == m - (m >> 1)) preb[rt] += preb[rs]; prew[rt] = prew[ls]; if(prew[ls] == m - (m >> 1)) prew[rt] += prew[rs]; sufb[rt] = sufb[rs]; if(sufb[rs] == (m >> 1)) sufb[rt] += sufb[ls]; sufw[rt] = sufw[rs]; if(sufw[rs] == (m >> 1)) sufw[rt] += sufw[ls]; mxb[rt] = max(mxb[ls], mxb[rs], preb[rs] + sufb[ls]); mxw[rt] = max(mxw[ls], mxw[rs], prew[rs] + sufw[ls]);}void Exc(int rt){ swap(preb[rt],prew[rt]); swap(sufb[rt],sufw[rt]); swap(sumb[rt],sumw[rt]); swap(mxb[rt],mxw[rt]);}void push_dn(int rt, int m){ if(Xor[rt]){//异或是lazy,又是必须 Xor[ls] ^= 1; Xor[rs] ^= 1; Exc(ls); Exc(rs); Xor[rt] = 0; } if(sumb[rt] == m){ preb[ls] = sufb[ls] = mxb[ls] = sumb[ls] = m - (m >> 1); preb[rs] = sufb[rs] = mxb[rs] = sumb[rs] = (m >> 1); prew[ls] = sufw[ls] = mxw[ls] = sumw[ls] = 0; prew[rs] = sufw[rs] = mxw[rs] = sumw[rs] = 0; }else if(sumw[rt] == m){ preb[ls] = sufb[ls] = mxb[ls] = sumb[ls] = 0; preb[rs] = sufb[rs] = mxb[rs] = sumb[rs] = 0; prew[ls] = sufw[ls] = mxw[ls] = sumw[ls] = m - (m >> 1); prew[rs] = sufw[rs] = mxw[rs] = sumw[rs] = (m >> 1); }}void build(int l , int r, int rt){ Xor[rt] = 0; if(l == r) { scanf("%d",&tmp); if(tmp){ preb[rt] = sufb[rt] = mxb[rt] = sumb[rt] = 1; prew[rt] = sufw[rt] = mxw[rt] = sumw[rt] = 0; }else{ preb[rt] = sufb[rt] = mxb[rt] = sumb[rt] = 0; prew[rt] = sufw[rt] = mxw[rt] = sumw[rt] = 1; } return ; } havem; build(lson); build(rson); push_up(rt, r - l + 1);}void update(int L, int R, int op, int l, int r, int rt){ if(L <= l && r <= R){ if(op == 0){ preb[rt] = sufb[rt] = mxb[rt] = sumb[rt] = 0; prew[rt] = sufw[rt] = mxw[rt] = sumw[rt] = r - l + 1; return ; }else if(op == 1){ preb[rt] = sufb[rt] = mxb[rt] = sumb[rt] = r - l + 1; prew[rt] = sufw[rt] = mxw[rt] = sumw[rt] = 0; return; } Exc(rt); Xor[rt] ^= 1; return ; }havem; push_dn(rt, r - l + 1); if(L <= m) update(L,R,op,lson); if(R > m) update(L,R,op,rson); push_up(rt,r - l + 1);}int query3(int L, int R, int l, int r, int rt){//3 all 1's ; 4 longest 1's if(L <= l && r <= R){ return sumb[rt]; } havem; push_dn(rt, r - l + 1); int ret = 0; if(L <= m) ret += query3(L,R,lson); if(R > m) ret += query3(L,R,rson); return ret;}int query4(int L, int R, int l, int r, int rt){//3 all 1's ; 4 longest 1's if(L <= l && r <= R){ return mxb[rt]; } havem; push_dn(rt, r - l + 1); if(R <= m) return query4(L,R,lson); if(L > m) return query4(L,R,rson); int ret = max(query4(L,R,lson), query4(L,R,rson)); ret = max(ret, min(m - L + 1, sufb[ls]) + min(R - m, preb[rs]) ); return ret;}int main(){ scanf("%d",&T); while(T --){ scanf("%d%d",&n,&Q); build(0,n - 1,1);// for(int i = 0; i < Q; i ++){ scanf("%d%d%d",&op,&a,&b); if(op == 0){ update(a,b,op,0,n - 1,1);//期间全变为0 }else if(op == 1){ update(a,b,op,0,n - 1,1);//期间全变为1 }else if(op == 2){ update(a,b,op,0,n - 1,1);//期间0,1互换 }else if(op == 3){ printf("%d\n",query3(a,b,0,n - 1,1) );//all 1's in [a,b] }else{ printf("%d\n",query4(a,b,0,n - 1,1) );//longest 1's in [a,b] } } }return 0;}
#include <cstdio>using namespace std;#define maxn 100010#define lson l, m , rt << 1#define rson m + 1, r, rt << 1 | 1#define ls rt << 1#define rs rt << 1 | 1#define havem int m = (l + r ) >> 1int n,Q,a,b,T;//首先得声明,cov不是lazy标志,不然是不会出现在push_up里面的int cov[maxn << 2],ri, max_len,cur_len;void push_up(int rt){ if(cov[ls] == cov[rs])//cov 可以为-1 cov[rt] = cov[ls]; else cov[rt] = -1;}void build(int l , int r, int rt){ if(l == r){ scanf("%d",&cov[rt]); return ; }havem; build(lson); build(rson); push_up(rt);}void push_dn(int rt){ if(cov[rt] >= 0){ cov[ls] = cov[rs] = cov[rt]; cov[rt] = -1; }}void update(int L, int R, int val, int l, int r, int rt){ if(cov[rt] == val) return ; if(L <= l && r <= R){ cov[rt] = val; return; }push_dn(rt); havem; if(L <= m) update(L,R,val,lson); if(R > m) update(L,R,val,rson); push_up(rt);}void update_xor(int L,int R, int l, int r, int rt){ if(L <= l && r <= R && cov[rt] >= 0){ cov[rt] ^= 1; return ; }push_dn(rt); havem; if(L <= m) update_xor(L,R,lson); if(R > m) update_xor(L,R,rson); push_up(rt);}int query(int L, int R, int l, int r, int rt){ if(L <= l && r <= R){ if(cov[rt] == 0){ return 0; } if(cov[rt] == 1){ return r - l + 1; } } havem; push_dn(rt); if(R <= m) return query(L , R, lson); if(L > m) return query(L,R,rson); return query(L , R , lson) + query(L,R,rson);}void queryl(int L,int R, int l, int r, int rt){ if(cov[rt] == 0) return ; if(L <= l && r <= R && cov[rt] == 1){ if(L == ri + 1) //现在这个区间如果接着上个区间 cur_len += r - l + 1; else cur_len = r - l + 1; if(cur_len > max_len) max_len = cur_len; ri = r; return ; }push_dn(rt); havem; if(R <= m) queryl(L , R, lson); else if(L > m) queryl(L,R,rson); else//这里是m和m + 1, 这里我wa了很久,这跟上面的L == ri + 1有关 queryl(L , m , lson), queryl( m + 1 ,R,rson);}int main(){ scanf("%d",&T); int op,a,b; while(T --){ scanf("%d%d",&n,&Q); build(1,n,1); while(Q --){ scanf("%d%d%d",&op,&a,&b); a ++, b ++; switch(op){ case 0 : update(a,b,0,1,n,1); break; case 1: update(a,b,1,1,n,1); break; case 2: update_xor(a,b,1,n,1); break; case 3: printf("%d\n",query(a,b,1,n,1) ); break; case 4: max_len = cur_len = 0; ri = 0; queryl(a,b,1, n, 1); printf("%d\n",max_len); } } }}
- hdu 3397 线段树前后缀blahblah Sequence operation
- 线段树 HDU 3397 Sequence operation
- HDU 3397 Sequence operation (线段树)
- HDU 3397 Sequence operation (线段树)
- HDU 3397 Sequence operation (线段树)
- hdu 3397 Sequence operation 线段树
- hdu 3397 Sequence operation 线段树
- HDU 3397 Sequence operation(线段树)
- HDU 3397 Sequence operation 线段树
- hdu 3397 Sequence operation 线段树
- hdu 3397 Sequence operation(线段树)
- HDU 3397 Sequence operation(线段树)
- HDU - 3397 Sequence operation(线段树)
- hdu 3397 Sequence operation(线段树)
- HDU 3397 Sequence operation 线段树(区间合并)
- hdu 3397 Sequence operation(线段树的各种操作)
- hdu 3397 Sequence operation(很有意思的线段树题)
- hdu 3397 Sequence operation(线段树,lazy,区间合并)
- 【Windows8开发】异步编程进阶篇之 create_async, create_task, make_task区别与联系
- 九一八,勿忘国耻,抵制苍井空,还我钓鱼岛。
- Android4.0.3/Android4.2.2 添加 Ethernet
- mybatis There is no getter for property named 'xx' in 'class java.lang.String
- MyBATIS(即iBATIS)问题集
- hdu 3397 线段树前后缀blahblah Sequence operation
- 如何在WinRT中调用类似STL的Vector和Map
- ubuntu下配置dns
- jquery 遍历控件
- openstack创建instance的流程解析
- ubuntu下配置nginx+keepalived做HA
- 可供借鉴的----实现Web平台升级的傻瓜化
- String StringBuffer StringBuilder 三者的区别
- 酷壳网陈皓:由12306.cn谈谈网站性能技术