【vijos】1881 闪烁的繁星(线段树+特殊的技巧)
这场比赛太难了sad。所以我都没做。。
这题一开始我竟然不会sad(本来就不会),然后我继续yy。。yy了好久,竟然yy了个什么可拆分的并查集?(sad,后来发现我是如此sb,根本无法实现。。)
然后我弃疗了,比赛干脆不交了。。sad
后来看了题解和神犇们热心的指导,这就是一水题。。
sad。
我们只需要在线段树维护三个值,L表示这个节点的区间内从左边向又能延伸的最长可行串的长度,R表示这个节点的区间内从右边向左能延伸的最长可行串的长度,mx表示这个区间最长的可行串的长度。
那么我们在pushup里面只需要这样转移即可
void pushup(int x, int len) {
int l=lc, r=rc;
t[x].x=t[l].x;
t[x].y=t[r].y;
t[x].lx=t[l].lx;
t[x].rx=t[r].rx;
t[x].mx=max(t[l].mx, t[r].mx);
if(t[l].y!=t[r].x) {
t[x].mx=max(t[x].mx, t[l].rx+t[r].lx);
if(t[l].mx==(len-(len>>1))) t[x].lx=max(t[x].lx, t[l].mx+t[r].lx);
if(t[r].mx==(len>>1)) t[x].rx=max(t[x].rx, t[r].mx+t[l].rx);
}
}
这个多想想就知道为什么了。。。(因为我是蒟蒻所以我想不出来。orz
然后这题就成为水题了。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
#define printarr1(a, b) for1(_, 1, b) cout << a[_] << '\t'; cout << endl
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; }
const int N=200005;
#define lc x<<1
#define rc x<<1|1
#define lson l, m, lc
#define rson m+1, r, rc
#define MID (l+r)>>1 struct dat { int lx, rx, x, y, mx; }t[N<<2];
int n, Q;
void pushup(int x, int len) {
int l=lc, r=rc;
t[x].x=t[l].x;
t[x].y=t[r].y;
t[x].lx=t[l].lx;
t[x].rx=t[r].rx;
t[x].mx=max(t[l].mx, t[r].mx);
if(t[l].y!=t[r].x) {
t[x].mx=max(t[x].mx, t[l].rx+t[r].lx);
if(t[l].mx==(len-(len>>1))) t[x].lx=max(t[x].lx, t[l].mx+t[r].lx);
if(t[r].mx==(len>>1)) t[x].rx=max(t[x].rx, t[r].mx+t[l].rx);
}
}
void build(int l, int r, int x) {
t[x].mx=t[x].x=t[x].y=t[x].lx=t[x].rx=1;
if(l==r) return;
int m=MID;
build(lson); build(rson);
}
void upd(int l, int r, int x, int p) {
if(l==r) { t[x].x=t[x].y=!t[x].x; return; }
int m=MID;
if(p<=m) upd(lson, p); else upd(rson, p);
pushup(x, r-l+1);
}
int main() {
read(n); read(Q);
build(1, n, 1);
while(Q--) {
upd(1, n, 1, getint());
printf("%d\n", t[1].mx);
}
return 0;
}
背景
繁星闪烁着--深蓝的太空
何曾听得见他们对语
沉默中
微光里
他们深深的互相颂赞了
描述
繁星, 漫天的繁星.
繁星排成一列, 我数一数呀, 一共有N只小星星呢.
星星们是听话的好孩子, 小岛在指挥它们跳舞呢.
舞蹈开始前, 它们都亮了起来!
小岛指一指第i只小星星, 只见第i只小星星立刻改变了自己的状态.
如果它之前是亮着的, 那么立刻就灭掉了.
如果它之前是灭掉的, 现在就立刻亮了呀!
如果说, 可以有连续若干只小星星.
其中任意相邻两只星星状态不同.
那就是最美的了.
小岛希望知道:
每一次发出指令之后
能找到最长的连续小星星, 满足上述需求的
有多长?
格式
输入格式
第一行有两个整数, 分别为星星总数N, 和指令总数Q.
1<=N<=200,000; 1<=Q<=200,000.
之后Q行, 每行有一个整数i: 1<=i<=N, 表示小岛发出的指令.
输出格式
输出有Q行, 其中每i行有一个整数.
表示小岛的第i条指令发出之后, 可以找到的满足要求的最长连续星星序列有多长?
限制
对于20%的数据: N, Q <= 100.
对于30%的数据: N, Q <= 70000.
对于100%的数据: 1 <= N, Q <= 200,000.
提示
对于样例, 星星序列的状态依次为: OOOOOO -> OXOOOO -> OXOXOO
这里用O表示亮着的星星, 用X表示灭掉的星星.
【vijos】1881 闪烁的繁星(线段树+特殊的技巧)的更多相关文章
- Vijos1881闪烁的繁星 [线段树]
P1881闪烁的繁星 背景 繁星闪烁着--深蓝的太空何曾听得见他们对语沉默中微光里他们深深的互相颂赞了 描述 繁星, 漫天的繁星.繁星排成一列, 我数一数呀, 一共有N只小星星呢. 星星们是听话的好 ...
- Vijos 1083 小白逛公园(线段树)
线段树,每个结点维护区间内的最大值M,和sum,最大前缀和lm,最大后缀和rm. 若要求区间为[a,b],则答案max(此区间M,左儿子M,右儿子M,左儿子rm+右儿子lm). ----------- ...
- [vijos]1083小白逛公园<线段树>
描述 小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了. 一开始,小白就根据公园的风景给每个公 ...
- 【BZOJ】3339: Rmq Problem & 3585: mex(线段树+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=3585 好神的题. 但是!!!!!!!!!!!!!!我线段树现在要开8倍空间才能过!!!!!!!!!! ...
- 【POJ】2828 Buy Tickets(线段树+特殊的技巧/splay)
http://poj.org/problem?id=2828 一开始敲了个splay,直接模拟. tle了.. 常数太大.. 好吧,说是用线段树.. 而且思想很拽.. (貌似很久以前写过貌似的,,) ...
- 【BZOJ】1645: [Usaco2007 Open]City Horizon 城市地平线(线段树+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1645 这题的方法很奇妙啊...一开始我打了一个“离散”后的线段树.............果然爆了. ...
- POJ2528Mayor's posters 线段树,离散化技巧
题意:一个坐标轴从1~1e7,每次覆盖一个区间(li,ri),问最后可见区间有多少个(没有被其他区间挡住的) 线段树,按倒序考虑,贴上的地方记为1,每次看(li,ri)这个区间是否全是1,全是1就说明 ...
- vijos 1081 野生动物园 函数式线段树
描述 cjBBteam拥有一个很大的野生动物园.这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域都饲养着一头狮子.这些狮子从北到南编号为1,2,3,…,N.每头狮子都有一个 ...
- 小结:线段树 & 主席树 & 树状数组
概要: 就是用来维护区间信息,然后各种秀智商游戏. 技巧及注意: 一定要注意标记的下放的顺序及影响!考虑是否有叠加或相互影响的可能! 和平衡树相同,在操作每一个节点时,必须保证祖先的tag已经完全下放 ...
随机推荐
- 一步一步学Spring.NET——1、Spring.NET环境准备
Spring.NET 1.3.2下载地址:http://down.51cto.com/data/861700 下载后解压 Spring.NET-1.3.2.7z:这个里面有我们须要用到的全部东西. S ...
- 2、jQuery选择器
2.1 基本选择器 它有元素Id.Class.元素名.多个选择符组成,通过基本选择器可以实现大多数页面元素的查找. 选择器 功能 返回值 #id 根据给定的ID匹配一个元素 单个元素 element ...
- 批量部署 自动化之 - [pssh](转)
并行执行命令工具简介 作为运维工程师来讲,机器数量到一定级别的时候,批量运维和管理机器就是一件费神的事情,还好有很多可以批量并行执行命令的工具,比如 pssh , python fabrictaoba ...
- sql jion
A Visual Explanation of SQL Joins I thought Ligaya Turmelle's post on SQL joins was a great primer f ...
- 【前端】JavaScript
一.JavaScript概述 1.JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEa ...
- bootstrap学习笔记 Bootstrap 列表组
本文将介绍列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素ul 添加class list-group 向li添加class list-group-ite ...
- web开发中常见的安全漏洞及避免方法
1.安全攻击 1.SQL.HTML.JS.OS命令注入 2.XSS跨站脚本攻击,利用站内信任的用户,在web页面插入恶意script代码 3.CSRF跨站请求伪造,通过伪装来自信任用户的请求来利用受信 ...
- ASP.NET CORE 2.1无法添加控制器、视图
常规操作:右键Controllers,添加控制器 结果提示:运行所选代码生成器时出错 在控制器里快速添加视图也得到同样的错误提示 既然提示代码生成器了,对比了一下2.0和2.1的代码,发现2.1默认没 ...
- leetcode——Lowest Common Ancestor of a Binary Tree
题目 Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. 思路 这一次 ...
- PowerShell---Operators 介绍
1.Arithmetic operators(算术运算符) 算术运算符包括加.减.乘.除.取模 此外,加法运算符 (+) 和乘法运算符 (*) 还可对字符串.数组和哈希表进行运算.加法运算符将输入连接 ...