您的位置:首页 > 其它

1881闪烁的繁星——线段树vijos

2015-02-08 09:53 337 查看
对于这道题 是一道裸线段树 从单点修改 全局查询 一眼看出线段树。。O(∩_∩)O~

只不过这道题相较于原线段树 多了一个判定

即当tree[i]的左儿子 右儿子 的中间部分可以相连接构成一个更大的序列时的特判

可以开一个数组a[i]记录当前点的明灭状况 -1为明 1为灭 每次改变状态就是a[i]*=-1;

若左儿子右端点为 r 右儿子左端点为 l

当a[l]+a[r]==0

则可以连接

则父节点的maxlong 为 左儿子的maxlong 右儿子的maxlong 中间连接后的长度 中的最大值

并更新 父节点的 左起长度 右起长度 (这部分原理以及做法就自己想吧)

然后就递归了


背景

繁星闪烁着--深蓝的太空

何曾听得见他们对语

沉默中

微光里

他们深深的互相颂赞了


描述

繁星, 漫天的繁星.

繁星排成一列, 我数一数呀, 一共有N只小星星呢.

星星们是听话的好孩子, 小岛在指挥它们跳舞呢.

舞蹈开始前, 它们都亮了起来!

小岛指一指第i只小星星, 只见第i只小星星立刻改变了自己的状态.

如果它之前是亮着的, 那么立刻就灭掉了.

如果它之前是灭掉的, 现在就立刻亮了呀!

如果说, 可以有连续若干只小星星.

其中任意相邻两只星星状态不同.

那就是最美的了.

小岛希望知道:

每一次发出指令之后

能找到最长的连续小星星, 满足上述需求的

有多长?


格式

输入格式

第一行有两个整数, 分别为星星总数N, 和指令总数Q.

1<=N<=200,000; 1<=Q<=200,000.

之后Q行, 每行有一个整数i: 1<=i<=N, 表示小岛发出的指令.

输出格式

输出有Q行, 其中每i行有一个整数.

表示小岛的第i条指令发出之后, 可以找到的满足要求的最长连续星星序列有多长?


样例1

样例输入1[复制]

6 224

样例输出1[复制]

35


限制

对于20%的数据: N, Q <= 100.

对于30%的数据: N, Q <= 70000.

对于100%的数据: 1 <= N, Q <= 200,000.


提示

对于样例, 星星序列的状态依次为: OOOOOO -> OXOOOO -> OXOXOO

这里用O表示亮着的星星, 用X表示灭掉的星星.

#include<iostream>
#include<cstdio>
#include<cstring> 
#define MAXN 200000+10
using namespace std;
int a[200000+10];
struct node
{
<span style="white-space:pre">	</span>int l,r;
<span style="white-space:pre">	</span>int maxlong;
<span style="white-space:pre">	</span>int leftlong;
<span style="white-space:pre">	</span>int rightlong;
<span style="white-space:pre">	</span>node()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>maxlong=1;
<span style="white-space:pre">		</span>leftlong=1;
<span style="white-space:pre">		</span>rightlong=1;
<span style="white-space:pre">	</span>}
}tree[800000+10];
int n,q;
int readdata()
{
<span style="white-space:pre">	</span>scanf("%d%d",&n,&q);
}
void build(int l,int r,int m)
{
<span style="white-space:pre">	</span>tree[m].l=l;
<span style="white-space:pre">	</span>tree[m].r=r;
<span style="white-space:pre">	</span>if(l==r)
<span style="white-space:pre">	</span>return;
<span style="white-space:pre">	</span>int mid=(l+r)/2;
<span style="white-space:pre">	</span>build(l,mid,2*m);
<span style="white-space:pre">	</span>build(mid+1,r,2*m+1);<span style="white-space:pre">	</span>
}
void change(int m,int c)
{
<span style="white-space:pre">	</span>if(tree[m].l==tree[m].r&&tree[m].l==c)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>a[c]*=-1;
<span style="white-space:pre">		</span>return;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>int ll=tree[m].l;
<span style="white-space:pre">	</span>int rr=tree[m].r;
<span style="white-space:pre">	</span>int mid=(ll+rr)/2;
<span style="white-space:pre">	</span>if(c<=mid)
<span style="white-space:pre">	</span>change(m*2,c);
<span style="white-space:pre">	</span>else change(m*2+1,c);
<span style="white-space:pre">	</span>if(a[tree[2*m].r]+a[tree[2*m+1].l]==0)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>tree[m].maxlong=max(tree[2*m].rightlong+tree[2*m+1].leftlong,tree[2*m+1].maxlong);
<span style="white-space:pre">		</span>tree[m].maxlong=max(tree[m].maxlong,tree[2*m].maxlong);<span style="white-space:pre">			</span>
<span style="white-space:pre">		</span>if(tree[2*m].leftlong==tree[2*m].r-tree[2*m].l+1)
<span style="white-space:pre">		</span>tree[m].leftlong=tree[2*m].leftlong+tree[2*m+1].leftlong;
<span style="white-space:pre">		</span>else tree[m].leftlong=tree[2*m].leftlong;<span style="white-space:pre">			</span>
<span style="white-space:pre">		</span>if(tree[2*m+1].rightlong==tree[2*m+1].r-tree[2*m+1].l+1)
<span style="white-space:pre">		</span>tree[m].rightlong=tree[2*m+1].rightlong+tree[2*m].rightlong;
<span style="white-space:pre">		</span>else tree[m].rightlong=tree[2*m+1].rightlong;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>else
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>tree[m].maxlong=max(tree[2*m].maxlong,tree[2*m+1].maxlong);
<span style="white-space:pre">		</span>tree[m].leftlong=tree[2*m].leftlong;
<span style="white-space:pre">		</span>tree[m].rightlong=tree[2*m+1].rightlong;
<span style="white-space:pre">	</span>}<span style="white-space:pre">	</span>
}
void work()
{
<span style="white-space:pre">	</span>int co=0;
<span style="white-space:pre">	</span>for(int i=1;i<=q;i++)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>scanf("%d",&co);
<span style="white-space:pre">		</span>change(1,co);
<span style="white-space:pre">		</span>printf("%d\n",tree[1].maxlong);
<span style="white-space:pre">	</span>}
}
int main()
{
<span style="white-space:pre">	</span>memset(a,-1,sizeof(a));
<span style="white-space:pre">	</span>readdata();
<span style="white-space:pre">	</span>build(1,n,1);
<span style="white-space:pre">	</span>work();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: