线段树练习 区间合并
2012-04-03 18:45
211 查看
题目链接http://www.codeforces.com/problemset/problem/145/E
蛮好的题目
一连串由4、7组成的字符串
两种操作:count 输出整个区间内最长的不下降子序列的长度
switch a b 将a、b之间的数4变成7 7变成4
注意,最长不下贱子序列不一定要连续
一般情况下,不连续的最长不下降子序列的长度是无法维护的,但是这道题目的特殊性显而易见,只有4 7 两种数字,相当于0 1
做法:
1:分别记录区间最长不下降和最长不上升的序列的长度,这样子进行异或操作的时候可以直接互换
2:记录区间0的个数和1的个数,利用这两个信息可以 在将信息往上传的时候 维护区间最长的不下降和不上升序列的长度,这里仔细想想
View Code
蛮好的题目
一连串由4、7组成的字符串
两种操作:count 输出整个区间内最长的不下降子序列的长度
switch a b 将a、b之间的数4变成7 7变成4
注意,最长不下贱子序列不一定要连续
一般情况下,不连续的最长不下降子序列的长度是无法维护的,但是这道题目的特殊性显而易见,只有4 7 两种数字,相当于0 1
做法:
1:分别记录区间最长不下降和最长不上升的序列的长度,这样子进行异或操作的时候可以直接互换
2:记录区间0的个数和1的个数,利用这两个信息可以 在将信息往上传的时候 维护区间最长的不下降和不上升序列的长度,这里仔细想想
View Code
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 1000010; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 char str[maxn]; struct node{ int col; int n0,n1,sum,ld; void make(){ col^=1; n0^=n1;n1=n0^n1;n0^=n1; sum^=ld;ld=sum^ld;sum^=ld; } void init(){ col=n0=n1=sum=ld=0; } }a[maxn<<2]; int max(int a,int b){ return a>b?a:b; } void pushdown(int rt){ if(a[rt].col){ a[rt].col=0; a[rt<<1].make(); a[rt<<1|1].make(); } } void pushup(int rt){ a[rt].n0=a[rt<<1].n0+a[rt<<1|1].n0; a[rt].n1=a[rt<<1].n1+a[rt<<1|1].n1; a[rt].sum=max(a[rt<<1].sum+a[rt<<1|1].n1,a[rt<<1|1].sum+a[rt<<1].n0); a[rt].ld=max(a[rt<<1].ld+a[rt<<1|1].n0,a[rt<<1|1].ld+a[rt<<1].n1); } void update(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R){ a[rt].make(); return ; } pushdown(rt); int m=(l+r)>>1; if(L<=m) update(L,R,lson); if(R>m) update(L,R,rson); pushup(rt); } void build(int l,int r,int rt){ a[rt].init(); if(l==r){ a[rt].n1=(str[l]=='7'); a[rt].n0=!a[rt].n1; a[rt].ld=a[rt].sum=1; return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt); } int main(){ int n,m,l,r; char op[10]; scanf("%d%d",&n,&m); scanf("%s",str+1); build(1,n,1); while(m--){ scanf("%s",op); if(op[0]=='s') { scanf("%d%d",&l,&r); update(l,r,1,n,1); } else printf("%d\n",a[1].sum); } }
相关文章推荐
- 线段树练习——区间合并
- 线段树练习 区间合并
- HDU 3397 Sequence operation(线段树区间合并+区间修改)
- hdu 5367(线段树+区间合并)
- poj 3667 线段树合并区间
- hdu1540 Tunnel Warfare 线段树区间合并
- hdu 4453 约会安排(线段树区间合并)
- HDU 1540 Tunnel Warfare 线段树:单点更新,区间合并
- 牛客网NowCoder 2018年全国多校算法寒假训练营练习比赛(第五场)A.逆序数 B.Big Water Problem(线段树-区间查询求和和单点更新) F.The Biggest Water Problem H.Tree Recovery(线段树-区间查询求和和区间更新)
- HDU1540:Tunnel Warfare(线段树区间合并)
- POJ3667:Hotel(线段树区间合并)
- Codeforces Round #222 (Div. 1) D. Developing Game 线段树有效区间合并
- Poj 3667 Hotel 线段树 区间合并
- 【HDU - 3911】Black And White 【线段树+区间操作+区间合并】
- HDU 3308 LCIS(线段树区间合并)
- HDU 5316 Magician(线段树区间合并, 子序列最值 多校2015啊)
- POJ 3667 Hotel 带区间合并操作的线段树
- 团体程序设计天梯赛-练习集-L3-002. 堆栈(线段树-区间第k大)
- POJ3667-Hotel-线段树区间合并(模板)
- hdu3308 线段树区间合并