题目描述:

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

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

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

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

解题报告:

用时3h,2WA

这一题开始想着优化\(O(n^2)\)的暴力,并没有成功,然后请教大佬,得知是分治,然后花了3h才弄出这个分治,分治函数里必须数线性的,所以考虑怎么算贡献,发现只需要讨论最大值和最小值分别再\((l,mid)\)还是\((mid+1,r)\)

首先是全部在左边的,那么就可以确定右端点的位置,全在右边的同理

难点在于分别在左右两端的:

我们考虑左边是最小值,右边是最大值

那么对于\(R-L=Max-Min\)这个式子我们可以拆成:\(R-Max=L-Min\)就可以把\(R-Max\)放进桶里,然后统计\(L-Min\)即可,然后我就傻逼的放进了桶里,并没有维护左边最小值小于右边最小值,左边最大值小于右边最大值这两个条件,然后答案大了许多,所以要开两个单调指针维护左边最小值小于右边最小值,左边最大值小于右边最大值这两个条件,注意数组要偏移

对于左边是最大值,右边是最小值的情况同理:

维护\(R+Min=L+Max\)即可

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=4e5+5;
struct node{
int x,y;
bool operator <(const node &r)const{
return x<r.x;
}
}a[N];
int n,L[N],R[N],t[N*3],mov=N;long long ans=0;
void solve(int l,int r){
if(l==r){
ans++;
return ;
}
int mid=(l+r)>>1;
solve(l,mid);solve(mid+1,r);
L[mid]=a[mid].y,R[mid]=a[mid].y;
for(int i=mid-1;i>=l;i--){
L[i]=Min(L[i+1],a[i].y);
R[i]=Max(R[i+1],a[i].y);
}
L[mid+1]=a[mid+1].y;R[mid+1]=a[mid+1].y;
for(int i=mid+2;i<=r;i++){
L[i]=Min(L[i-1],a[i].y);
R[i]=Max(R[i-1],a[i].y);
}
int j,k;
for(int i=mid;i>=l;i--){
k=R[i]-L[i]+1;
j=mid+(k-(mid-i+1));
if(j<=mid || j>r)continue;
if(R[j]>=L[i] && R[j]<=R[i] && L[j]>=L[i] && L[j]<=R[i])
ans++;
}
for(int i=mid+1;i<=r;i++){
k=R[i]-L[i]+1;
j=mid-(k-(i-mid+1));
if(j>=mid+1 || j<l)continue;
if(R[j]>=L[i] && R[j]<=R[i] && L[j]>=L[i] && L[j]<=R[i])
ans++;
}
int pr=mid+1,pl=mid+1;
for(int i=mid;i>=l;i--){
while(pr<=r && L[i]<L[pr])t[R[pr]-pr+mov]++,pr++;
while(pl<pr && R[i]>R[pl])t[R[pl]-pl+mov]--,pl++;
ans+=t[L[i]-i+mov];
}
for(int i=pl;i<pr;i++)t[R[i]-i+mov]--;
pr=mid;pl=mid;
for(int i=mid+1;i<=r;i++){
while(pr>=l && L[i]<L[pr])t[R[pr]+pr]++,pr--;
while(pl>pr && R[i]>R[pl])t[R[pl]+pl]--,pl--;
ans+=t[L[i]+i];
}
for(int i=pl;i>pr;i--)t[R[i]+i]--;
}
void work()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
}
sort(a+1,a+n+1);
solve(1,n);
printf("%lld\n",ans);
} int main()
{
work();
return 0;
}

51Nod 1555 布丁怪的更多相关文章

  1. 【51Nod1555】布丁怪

    [51Nod1555]布丁怪 题面 51Nod 题目大意: 给你一个\(n\times n\)的棋盘以及\(n\)个棋子,每个棋子坐标为\((x_i,y_i)\),保证棋盘的每一行或一列都有且仅有一个 ...

  2. 题解[51nod1555] 布丁怪

    题解[51nod1555] 布丁怪 题面 解析 本文参考这位dalao的题解 首先有一个巧妙的转换, 开一个数组记录每个横坐标的纵坐标, 简单来说就是对于点(x,y),令a[x]=y. 于是问题就变成 ...

  3. Codeforces 436D Pudding Monsters

    题意简述 开始有无限长的一段格子,有n个格子种有布丁怪兽,一开始连续的布丁怪兽算一个布丁怪兽. 每回合你可以将一个布丁怪兽向左或右移动,他会在碰到第一个布丁怪兽时停下,并与其合并. 有m个特殊格子,询 ...

  4. [CF436D]Pudding Monsters

    题目大意:有一个长度为$2\times 10^5$的板,有$n(n\leqslant 10^5)$个格子$a_1,\dots,a_n$有布丁怪兽,一开始连续的怪兽算一个怪兽,有$m(m\leqslan ...

  5. 51nod 2589 快速讨伐

    51nod 如果不考虑升级操作,只有买装备操作和打怪操作,那么首先一定要先买装备,然后可以打死1级的怪,这些怪被打死的时间只要在第一次买装备后面好了,因为现在总操作是\(n+\sum a_i\)个,所 ...

  6. 【51Nod 1244】莫比乌斯函数之和

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 模板题... 杜教筛和基于质因子分解的筛法都写了一下模板. 杜教筛 ...

  7. 51Nod 1268 和为K的组合

    51Nod  1268  和为K的组合 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使 ...

  8. 51Nod 1428 活动安排问题

    51Nod   1428  活动安排问题 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428 1428 活 ...

  9. 51Nod 1278 相离的圆

    51Nod 1278 相离的圆 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278 1278 相离的圆 基 ...

随机推荐

  1. 算法第四版 coursera公开课 普林斯顿算法 ⅠⅡ部分 Robert Sedgewick主讲《Algorithms》

    这是我在网上找到的资源,下载之后上传到我的百度网盘了. 包含两部分:1:算法视频的种子 2:字幕 下载之后,请用迅雷播放器打开,因为迅雷可以直接在线搜索字幕. 如果以下链接失效,请在下边留言,我再更新 ...

  2. 22.C++- 继承与组合,protected访问级别

    在C++里,通过继承和组合实现了代码复用,使得开发效率提高,并且能够通过代码看到事物的关系 组合比继承简单,所以在写代码时先考虑能否组合,再来考虑继承. 组合的特点 将其它类的对象作为当前类的成员使用 ...

  3. linux下面的智能解压脚本smart解压

    file命令可以辨别出一个给定文件的文件类型,如:file lf.gz,其输出结果为: lf.gz: gzip compressed data, deflated, original filename ...

  4. io文本加密

    文本加密习题 package io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Inpu ...

  5. c# 几种深拷贝方式的比较

    public static class Tools { //利用 BinaryFormatter 实现深拷贝 public static T DeepCopyByBinary<T>(thi ...

  6. nodejs 使用CAS 实现 单点登录(SSO) 【开源库实现,简单】

    大部分企业使用 java 开发业务系统, 针对java cas的认证 demo 比较多 ,还有PHPCAS ,标准的参考这里: phpCAS 的使用 整理登录流程如下图,图片来自网络 找了不少资料,n ...

  7. SpringBoot的注解:@SpringBootApplication注解 vs @EnableAutoConfiguration+@ComponentScan+@Configuration

    spring Boot开发者经常使用@Configuration,@EnableAutoConfiguration,@ComponentScan注解他们的main类, 由于这些注解如此频繁地一块使用( ...

  8. Django之Model进阶的更多操作

    Django之Model进阶的更多操作   一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) ...

  9. NHibernate从入门到精通系列(1)——NHibernate概括

    内容摘要 NHibernate简介 ORM简介 NHibernate优缺点 一.NHibernate简介 什么是?NHibernate?NHibernate是一个面向.NET环境的对象/关系数据库映射 ...

  10. JSON(一)——JSON与JavaScript的关系

    JSON是一种轻量级的数据交换格式,全称--JavaScript 对象表示法(JavaScript Object Notation). 类比XML,你可以把JSON看作是一种存储数据的格式类型,一种数 ...