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只小星星立刻改变了自己的状态.
如果它之前是亮着的, 那么立刻就灭掉了.
如果它之前是灭掉的, 现在就立刻亮了呀!
如果说, 可以有连续若干只小星星.
其中任意相邻两只星星状态不同.
那就是最美的了.
小岛希望知道:
每一次发出指令之后
能找到最长的连续小星星, 满足上述需求的
有多长?
1<=N<=200,000; 1<=Q<=200,000.
之后Q行, 每行有一个整数i: 1<=i<=N, 表示小岛发出的指令.
表示小岛的第i条指令发出之后, 可以找到的满足要求的最长连续星星序列有多长?
样例输入1[复制]
6 224
样例输出1[复制]
35
对于20%的数据: N, Q <= 100.
对于30%的数据: N, Q <= 70000.
对于100%的数据: 1 <= N, Q <= 200,000.
对于样例, 星星序列的状态依次为: OOOOOO -> OXOOOO -> OXOXOO
这里用O表示亮着的星星, 用X表示灭掉的星星.
只不过这道题相较于原线段树 多了一个判定
即当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(); }
相关文章推荐
- Vijos1881闪烁的繁星 [线段树]
- 【vijos】1881 闪烁的繁星(线段树+特殊的技巧)
- Vijos1881 闪烁的繁星
- Vijos P1881 闪烁的繁星
- Vijos P1881 闪烁的繁星
- Vijos P1881 闪烁的星星 (加强自己多一点。。)
- vijos p1881 线段树
- [线段树] [树状数组] [Vijos P1512] SuperBrother打鼹鼠 (mole)
- 【BZOJ】【P1756】【Vijos1083 小白逛公园】【题解】【线段树】
- [vijos 1448]: 校门外的树(树状数组/线段树)
- vijos国庆节模拟赛之繁星春水
- vijos - P1081野生动物园 (划分树 + 线段树)
- Vijos P1103 校门外的树【线段树,模拟】
- VIJOS国庆节模拟赛之繁星春水
- Vijos1881 闪烁的繁星
- Vijos 1404 遭遇战 - 动态规划 - 线段树 - 最短路 - 堆
- 【线段树】小白逛公园 Vijos1083
- 【线段树】bzoj1756 Vijos1083 小白逛公园
- VIJOS 1083 小白逛公园 线段树
- 【vijos】1750 建房子(线段树套线段树+前缀和)