题解 P1884 【[USACO12FEB]过度种植(银)Overplanting 】
什么,扫描线需要线段树?
那我第一个不干啊(其实是不会写)
这里介绍一种裸的扫描线:
我们根据x排序,对于相等的 \(x\) ,将 \(y\) 进入和退出分类讨论,然后全部放进set里面.每次 \(x\) 不相等的时候,答案就是 (现在y覆盖的乘以(现在的x-以前的x))
具体的判断方法:
1.y的判断:
将每个长方形的上方点记做出口,下方点记做入口.用一个set记录在某区间内所有的 \(y\) 值.每次从下往上扫,如果某个y是入口就将 \(sz\) +1,否则就将 \(sz\) -1.如果 \(sz\)==0 的时候就将你整个区间的值加到re里面

如图,每次x变的时候只需要保存中间y的值,然后用移动的x乘y就好了
注:我保存y进入和退出状态的原因就是为了记录中间是否有空位.可以发现,如果中间有空位,那么证明所有进入的点已经退出了,所以那一段不需要加上去(不懂可以画一下图)
long long query_up(){
long long re = 0,prev = -1,sz = 0;
for (multiset<pair<long long,bool> >::iterator i=se.begin();i!=se.end();++i){
pair<long long,bool> now = *i;
if (sz==0) {prev = now.f;sz++;}
else if (now.s) sz++;
else sz--;
if (sz==0) re+=(now.f-prev);//如果现在所以的y都已经出去了,那么答案就是最后一个y的出口-第一个y的入口
}
return re;
}
想到了这点以后这题的难点基本上就解决了.
因为有负数,我将每个数都加上了1e8,这样就可以完全不管负数了
不开long long见祖宗
完整代码:
#include <iostream>
#include <set>
#include <algorithm>
#include <iterator>
#include <utility>
using namespace std;
const long long MAXN = 1e5+5;
#define pp pair<long long,long long>
#define f first
#define s second
long long n,ans = 0;
multiset<pair<long long,bool> > se;
struct Edge{
long long x,y; bool in,in2;
}edge[MAXN*4];
Edge add_edge(long long a, long long b, bool bo,bool bo2){
Edge tmp;
tmp.x = a;
tmp.y = b;
tmp.in = bo;
tmp.in2 = bo2;
return tmp;
}
bool sorted(Edge a, Edge b){
return a.x<b.x;
}
long long query_up(){
long long re = 0,prev = -1,sz = 0;
for (multiset<pair<long long,bool> >::iterator i=se.begin();i!=se.end();++i){
pair<long long,bool> now = *i;
if (sz==0) {prev = now.f;sz++;}
else if (now.s) sz++;
else sz--;
if (sz==0) re+=(now.f-prev);
}
return re;
}
int main(){
cin >> n;
for (long long i=0;i<n;i++){
long long a,b,c,d; cin >> a >>b >> c >> d;
a+=1e8;b+=1e8;c+=1e8;d+=1e8;
edge[4*i] = add_edge(a,b,1,0);
edge[4*i+1] = add_edge(a,d,1,1);
edge[4*i+2] = add_edge(c,b,0,0);
edge[4*i+3] = add_edge(c,d,0,1);
//两种状态,第一种表示x变不变,第二种表示y变不变
}
sort(edge,edge+4*n,sorted);
long long prev = 0;
for (long long i=0;i<4*n;i++){
if (edge[i].x!=prev){//如果x变了
if (se.size()) ans += (edge[i].x-prev)*query_up();
prev = edge[i].x;
}
if (edge[i].in==1) se.insert(make_pair(edge[i].y,edge[i].in2));//如果这点是进入的点,就将y加入set
else se.erase(se.find(make_pair(edge[i].y,edge[i].in2)));
//否则将y扔出set
}
cout << ans;
}
留一组测试数据造福后人
3
3 7 7 3
1 5 5 1
2 2 7 -2
答案45
题解 P1884 【[USACO12FEB]过度种植(银)Overplanting 】的更多相关文章
- 线段树+扫描线【p1884】[Usaco12FEB]过度种植(银)Overplanting …
Description 在一个笛卡尔平面坐标系里(则X轴向右是正方向,Y轴向上是正方向),有\(N(1<=N<=1000)\)个矩形,第i个矩形的左上角坐标是\((x1, y1)\),右下 ...
- 「洛谷1884」「USACO12FEB」过度种植【离散化扫描线】
题目链接 [洛谷传送门] 题解 矩阵面积的并模板.(请求洛谷加为模板题) 很明显是要离散化的. 我们将矩阵与\(x\)轴平行的两个线段取出来.并且将这两个端点的\(x1\)和\(x2\)进行离散化. ...
- 洛谷P1884 [USACO12FEB]Overplanting S (矩形切割)
一种矩形切割的做法: 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const in ...
- [luogu] P2519 [HAOI2011]problem a (贪心)
P2519 [HAOI2011]problem a 题目描述 一次考试共有n个人参加,第i个人说:"有ai个人分数比我高,bi个人分数比我低."问最少有几个人没有说真话(可能有相同 ...
- usaco 2010年3月银组题解
usaco银组解题报告 一.石子游戏如果把‘O’当作0,‘X’当做1,则N个洞的每一种状态都可以看做是一个N位二进制数.于是,这个问题就变成了求环绕的N位格雷码.幸运的是,这个结构很容易就能够用一个简 ...
- 洛谷 P1821 [USACO07FEB]银牛派对Silver Cow Party 题解
P1821 [USACO07FEB]银牛派对Silver Cow Party 题目描述 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently ...
- 【luogu P1821 [USACO07FEB]银牛派对Silver Cow Party】 题解
题目链接:https://www.luogu.org/problemnew/show/P1821 反向多存一个图,暴力跑两遍 #include <cstdio> #include < ...
- USACO[19-20]Dec银组题解
1,MooBuzz 这题其实是道数学题. 我们先找找符合要求的数:1,2,4,7,8,11,13,14…… 我们发现再往后找都是这8个数中的一个加15k如:16……19……29…… 找规律发现k=n/ ...
- 【题解】Luogu p3047 [USACO12FEB]附近的牛Nearby Cows 树型dp
题目描述 Farmer John has noticed that his cows often move between nearby fields. Taking this into accoun ...
随机推荐
- cudaThreadSynchronize()
// 调用CUDA kernel 是非阻塞的,调用kernel语句后面的语句不等待kernel执行完,立即执行.所以在 call_kernel(see kernel.cu) 中执行 m5op.dump ...
- ZOJ 1409 communication system 双变量型的DP
这个题目一开始不知道如何下手,感觉很像背包,里面有两个变量,一个带宽B,一个价格P,有n个设备,每个设备有k个可选的器材(只需选一个),每个器材都有自己的B和P, n个设备选n个器材,最终,FB=所有 ...
- JVM学习与问题总结——java内存区域与内存溢出异常
java虚拟机将内存分为哪些区域? 根据Java SE7版本的Java虚拟机规范,虚拟机管理的内存包括5个运行时数据区域: 程序计数器 虚拟机栈 本地方法栈 方法区 堆 运行时数据区各部分的作用? 程 ...
- RF:connecting to multiple databases
Hello, I am trying to connect to multiple databases with DatabaseLibrary but its not working. *** Se ...
- 每天一点点之 taro 框架开发 - taro静态资源引入
1.说明: taro中客园自由的引用静态资源,不需要安装任何的loader 引用样式文件 通过ES6的import引入 2.引用js文件 import { functionName } from '. ...
- POJ 1050:To the Max
To the Max Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 43241 Accepted: 22934 Desc ...
- Java虚拟机之内存模型
一.java并发基础 在并发编程中存在两个关键问题①线程之间如何通信 ②线程之间如何同步. 通信 通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. ...
- Essay写作常见问题解析
Essay是西方大学的主要考核形式之一.其理念是考核学生对资料信息的吸取和观点的输出能力.可是对于刚踏入美国大学的国际留学生来说,写Essay就像是一种水土不服.各种不适和挣扎是不可避免的!今天小编来 ...
- Flink与Spark Streaming在与kafka结合的区别!
本文主要是想聊聊flink与kafka结合.当然,单纯的介绍flink与kafka的结合呢,比较单调,也没有可对比性,所以的准备顺便帮大家简单回顾一下Spark Streaming与kafka的结合. ...
- MFC下的网络编程(1)CAsyncSocket进行无连接(UDP)通信
服务器端发送数据给客户端 先看服务器端: CAsyncSocket m_sockSend; //声明一个Socket对象 点击发送数据后,执行下面这些动作 ...