- 闪烁的繁星
- 2014-10-08 22:37:00 @
线段树维护的是线段两头的颜色、线段左端最长的长度、线段右端最长的长度、线段内最长的长度
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=200005;
int mid[maxn*4],Left[maxn*4],Right[maxn*4];
bool ll[maxn*4],rr[maxn*4];
int n;
int q;
int p;
int max(int a,int b)
{
return a>b?a:b;
}
void merge(int o,int l,int r)
{
int lc=o<<1,rc=(o<<1)+1;
int m=(l+r)>>1;
ll[o]=ll[lc];
rr[o]=rr[rc];
mid[o]=max(mid[lc],mid[rc]);
if(ll[rc]!=rr[lc])
{
mid[o]=Left[rc]+Right[lc];
}
Left[o]=Left[lc];
if(mid[lc]==(m-l+1) && ll[rc]!=rr[lc])
{
Left[o]=Left[rc]+Right[lc];
}
Right[o]=Right[rc];
if(mid[rc]==(r-m) && ll[rc]!=rr[lc])
{
Right[o]=mid[rc]+Right[lc];
}
}
void build(int o,int l,int r)
{
if(l==r)
{
mid[o]=Left[o]=Right[o]=1;
ll[o]=rr[o]=0;
return;
}
int lc=o<<1,rc=(o<<1)+1;
int m=(l+r)>>1;
build(lc,l,m);
build(rc,m+1,r);
merge(o,l,r);
}
void update(int o,int l,int r)
{
if(l==r)
{
ll[o]=!ll[o];
rr[o]=!rr[o];
return;
}
int m=(l+r)>>1;
if(m>=p)
{
update(o<<1,l,m);
}
else
{
update((o<<1)+1,m+1,r);
}
merge(o,l,r);
}
int main()
{
cin>>n>>q;
int i;
build(1,1,n);
for(i=1;i<=q;i++)
{
scanf("%d",&p);
update(1,1,n);
printf("%d\n",mid[1]);
}
return 0;
}
0 条评论
信息
- ID
- 1881
- 难度
- 7
- 分类
- (无)
- 标签
- (无)
- 递交数
- 717
- 已通过
- 139
- 通过率
- 19%
- 被复制
- 3
- 上传者