51nod-1555:布丁怪

题目来源:  CodeForces
基准时间限制:1.5 秒 空间限制:131072 KB 分值: 320  难度:7级算法题
 收藏
 关注

布丁怪这一款游戏是在一个n×n 的矩形网格中进行的,里面有n个网格有布丁怪,其它的一些格子有一些其它的游戏对象。游戏的过程中是要在网格中移动这些怪物。如果两个怪物碰到了一起,那么他们就会变成一个更大的怪物。(谁叫他们是布丁呢?)

据统计,如果每一行每一列都只有一个布丁怪,那么这样的布局是比较吸引玩家的。

所以为了产生多种多样的有趣布局,我们会从一个 n×n 的有趣的地图中选取一个k×k (1≤k≤n)子矩形作为地图,而且这个子地图中恰好有k个布丁怪。

现在请你计算一下一个n×n 的有趣布局中,有多少种子地图是有趣的。


Input
单组测试数据。
第一行有一个整数n (1≤n≤3×10^5),表示原始地图的大小。
接下来n行,表示怪物的原始座标。
第i行有两个整数ri,ci(1≤ri,ci≤n),表示第i个怪物所在的行和列。
输入保证所有ri是不一样的,所有ci也是不一样的。
Output
输出一个整数,表示有多少种子地图是有趣的。
Input示例
样例输入1
5
1 1
4 3
3 2
2 4
5 5
Output示例
样例输出1
10


http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1555

分治:

对于区间[l, r]内所有的有趣块,可以分成三种

A:完全在[l, m)区间中

B:完全在[m+1, r]区间中

C:包含轴线m,其中m=(l+r)/2

对于前两种A和B,属于子问题求和即可,对于第三种C需要在分治时计算

那么如何计算?

可以将C再分为两种情况

①:有趣块中最左边的布丁怪和最右边的布丁怪都在同一侧,例如都在[l, m]区间中,或都在[m+1, r]区间中

②:有趣块中最左边的布丁怪和最右边的布丁怪不在同一侧

再对两种情况分别计算即可


#include<stdio.h>
#include<algorithm>
using namespace std;
int a[300005], sum[300005], Min[300005], Max[300005];
long long ans;
void Div(int l, int r);
int main(void)
{
	int n, i, x, y;
	scanf("%d", &n);
	for(i=1;i<=n;i++)
	{
		scanf("%d%d", &x, &y);
		a[x] = y;
	}
	Div(1, n);
	printf("%lld\n", ans);
	return 0;
}

void Div(int l, int r)
{
	int m, i, L, R, now;
	m = (l+r)/2;
	if(l>r)
		return;
	Max[m+1] = Min[m+1] = a[m+1];
	Max[m] = Min[m] = a[m];
	for(i=m+2;i<=r;i++)
		Max[i] = max(Max[i-1], a[i]), Min[i] = min(Min[i-1], a[i]);
	for(i=m-1;i>=l;i--)
		Max[i] = max(Max[i+1], a[i]), Min[i] = min(Min[i+1], a[i]);
/*********************************************************************************/
	for(i=m+1;i<=r;i++)					//情况①
	{
		now = i-Max[i]+Min[i];			//now是有趣块下边界,i是上边界,下面同理
		if(now<=m && now>=l && Min[now]>Min[i] && Max[now]<Max[i])
			ans++;
	}
	for(i=m;i>=l;i--)
	{
		now = i-Min[i]+Max[i];
		if(now>=m && now<=r && Min[now]>=Min[i] && Max[now]<=Max[i])
			ans++;
	}
/*********************************************************************************/
	L = R = m+1;						//情况②
	for(i=m;i>=l;i--)				//最左边的布丁怪在区间[1,m]中
	{
		while(R<=r && Min[R]>Min[i])
			sum[Max[R]-R+m]++, R++;
		while(L<R && Max[L]<Max[i])
			sum[Max[L]-L+m]--, L++;
		ans += sum[Min[i]+m-i];
	}
	while(L<R)
		sum[Max[L]-L+m]--, L++;			//初始化sum数组,不能用memset
	L = R = m;
	for(i=m+1;i<=r;i++)				//最左边的布丁怪在区间[m+1, r]中
	{
		while(R>=l && Min[R]>Min[i])
			sum[Max[R]+R-m]++, R--;
		while(L>R && Max[L]<Max[i])
			sum[Max[L]+L-m]--, L--;
		ans += sum[Min[i]-m+i];
	}
	while(L>R)
		sum[Max[L]+L-m]--, L--;
	Div(l, m-1);
	Div(m+1, r);
}


内容概要:本文详细介绍了一个基于Java+Vue的深度学习遥感建筑物提取与变化检测系统的设计与实现。系统融合多源遥感数据预处理、U-Net建筑物分割、孪生神经网络变化检测等核心技术,构建从前端交互、后端任务调度到模型推理的完整闭环。项目涵盖需求分析、数据库设计(MySQL)、API接口规范、前后端功能模块实现(含代码示例)、系统部署与未来优化方向,实现了遥感影像上传、自动分割、多时相变化检测、结果可视化与报告导出等全流程功能。系统具备高自动化、强交互性、可扩展性和安全合规等特点,适用于城市规划、灾害监测、土地调查等多个领域。; 适合人群:具备Java、Vue前端及深度学习基础知识的研发人员、GIS开发工程师、遥感数据分析师,以及从事智慧城市、自然资源管理等相关领域的技术人员。; 使用场景及目标:①应用于城市精细化管理、灾害应急响应、房地产监控等场景,实现建筑物动态变化的智能识别与可视化分析;②作为深度学习与遥感技术融合的教学案例,帮助开发者掌握前后端分离架构、模型集成、大规模数据处理与系统部署的综合技能;③为企业或科研机构提供可二次开发的开源框架,支持定制化模型接入与业务扩展。; 阅读建议:建议结合文档中的代码示例与系统架构图进行实践,重点关注前后端交互逻辑、深度学习模型调用方式及数据库设计。在学习过程中可搭建本地开发环境,逐步实现各功能模块,并通过模拟数据验证系统流程。同时注意安全规范与性能优化策略,以提升系统的稳定性与实用性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值