【vijos】1881 闪烁的繁星(线段树+特殊的技巧)

本文探讨了一道关于星星状态变化的算法题,通过使用线段树来高效解决寻找最长连续不同状态星星序列的问题。介绍了如何在线段树中维护三个关键值,并展示了具体的代码实现。

https://vijos.org/p/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条指令发出之后, 可以找到的满足要求的最长连续星星序列有多长?

样例1

样例输入1[复制]

6 2
2
4

样例输出1[复制]

3
5

限制

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

提示

对于样例, 星星序列的状态依次为: OOOOOO -> OXOOOO -> OXOXOO
这里用O表示亮着的星星, 用X表示灭掉的星星.

转载于:https://www.cnblogs.com/iwtwiioi/p/4008223.html

内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值