码迷,mamicode.com
首页 > 其他好文 > 详细

vijos1881 闪烁的繁星

时间:2014-11-05 16:38:10      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:io   os   for   sp   div   bs   amp   ios   ui   

描述

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

星星们是听话的好孩子, 小岛在指挥它们跳舞呢.
舞蹈开始前, 它们都亮了起来!

小岛指一指第i只小星星, 只见第i只小星星立刻改变了自己的状态.
如果它之前是亮着的, 那么立刻就灭掉了.
如果它之前是灭掉的, 现在就立刻亮了呀!

如果说, 可以有连续若干只小星星.
其中任意相邻两只星星状态不同.
那就是最美的了.

小岛希望知道:
每一次发出指令之后
能找到最长的连续小星星, 满足上述需求的
有多长?

思路:赤裸裸的线段树,这是我做的第三个线段树,当然也是第一个updata比较长的。题意很好懂,但是updata比较的复杂,tree的结构体里要保存左右端点的颜色、最长长度和整个区间的最长长度,然后就是一个个的更新了。

code:

#include<iostream>

#include<cstdio>

using namespace std;

struct use{

int lc,rc,ls,rs,ws;

}tree[10000001];

void updata(int i,int l,int r)

{

int mid;

mid=(l+r)/2;

tree[i].lc=tree[i*2].lc;

tree[i].ls=tree[i*2].ls;

tree[i].rc=tree[i*2+1].rc;

tree[i].rs=tree[i*2+1].rs;

tree[i].ws=max(tree[i*2].ws,tree[i*2+1].ws);

if (tree[i*2].rc!=tree[i*2+1].lc)

{

tree[i].ws=max(tree[i].ws,tree[i*2].rs+tree[i*2+1].ls);

if (tree[i*2].ws==mid-l+1)

  tree[i].ls=tree[i].ls+tree[i*2+1].ls;

if (tree[i*2+1].ws==r-mid)

  tree[i].rs=tree[i].rs+tree[i*2].rs;

}

}

void build(int i,int l,int r)

{

int mid;

if (l==r)

{

tree[i].lc=tree[i].rc=0;

tree[i].ws=tree[i].ls=tree[i].rs=1;

return;

}

mid=(l+r)/2;

build(i*2,l,mid);

build(i*2+1,mid+1,r);

updata(i,l,r);

}

void insert(int i,int l,int r,int k)

{

int mid;

if (l==r&&l==k)

{

tree[i].lc=tree[i].rc=1-tree[i].lc;

return;

}

mid=(l+r)/2;

if (k<=mid) insert(i*2,l,mid,k);

else insert(i*2+1,mid+1,r,k);

updata(i,l,r);

}

int main()

{

int n,q,i,j,k;

scanf("%d%d",&n,&q);

build(1,1,n);

for (i=1;i<=q;++i)

{

  scanf("%d",&k);

  insert(1,1,n,k);

  printf("%d\n",tree[1].ws);

    }

vijos1881 闪烁的繁星

标签:io   os   for   sp   div   bs   amp   ios   ui   

原文地址:http://www.cnblogs.com/Rivendell/p/4076452.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!