题目传送门

  快速的列车

  慢速的列车

题目大意

  一个无限大的方格图内有$n$个黑点。问有多少个位置上下左右至少有一个黑点或本来是黑点。

  扫描线是显然的。

  考虑一下横着的线段,取它两个端点,横坐标小的地方放一个+1,大的地方放一个-1事件。

  然后扫描,扫到的横着的线段更新,竖着的线段用树状数组求答案。

  然后考虑这一列上原来存在的黑点有没有被统计,如果没有就加上。

Code

 /**
* bzoj
* Problem#1818
* Accepted
* Time: 1824ms
* Memory: 9776k
*/
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
#define smax(a, b) (a = max(a, b))
#define smin(a, b) (a = min(a, b))
typedef bool boolean;
#define ll long long const int N = 1e5 + ; typedef class IndexedTree {
public:
int s;
int* ar; IndexedTree() { }
IndexedTree(int s):s(s) {
ar = new int[(s + )];
memset(ar, , sizeof(int) * (s + ));
} void add(int idx, int val) {
for ( ; idx <= s; idx += (idx & (-idx)))
ar[idx] += val;
} int query(int idx) {
int rt = ;
for ( ; idx; idx -= (idx & (-idx)))
rt += ar[idx];
return rt;
}
}IndexedTree; typedef class Event {
public:
int x, y, val; Event(int x = , int y = , int val = ):x(x), y(y), val(val) { } boolean operator < (Event b) const {
return x < b.x;
}
}Event; int n;
int xs[N], ys[N], bxs[N], bys[N];
int ls[N], rs[N], us[N], ds[N];
ll res = ;
int tp = ;
Event es[N << ];
vector<int> vs[N];
IndexedTree it; inline void init() {
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%d%d", xs + i, ys + i);
} inline void descrete(int* ar, int* br, int n) {
memcpy(br, ar, sizeof(int) * (n + ));
sort(br + , br + n + );
for (int i = ; i <= n; i++)
ar[i] = lower_bound(br + , br + n + , ar[i]) - br;
} inline void solve() {
descrete(xs, bxs, n);
descrete(ys, bys, n); for (int i = ; i <= n; i++)
ls[i] = ds[i] = N;
for (int i = ; i <= n; i++)
us[i] = rs[i] = ; for (int i = ; i <= n; i++) {
smin(ls[ys[i]], xs[i]);
smax(rs[ys[i]], xs[i]);
smin(ds[xs[i]], ys[i]);
smax(us[xs[i]], ys[i]);
} for (int i = ; i <= n; i++)
vs[xs[i]].push_back(ys[i]); for (int i = ; i <= n; i++)
if (ls[i] < rs[i] - ) {
es[++tp] = Event(ls[i], i, );
es[++tp] = Event(rs[i], i, -);
}
sort(es + , es + tp + ); int pe = ;
it = IndexedTree(n);
bxs[] = -1e9 - ;
for (int i = ; i <= n; i++) {
if (bxs[i] == bxs[i - ]) continue;
while (pe <= tp && es[pe].x == i)
it.add(es[pe].y, es[pe].val), pe++;
if (ds[i] <= us[i])
res += it.query(us[i]) - it.query(ds[i] - );//, cerr << bxs[i] << endl;
for (int j = ; j < (signed) vs[i].size(); j++)
if (it.query(vs[i][j]) - it.query(vs[i][j] - ) == )
res++;
// cerr << bxs[i] << " " << res << endl;
}
printf(Auto"\n", res);
} int main() {
init();
solve();
return ;
}

bzoj 1818 [CQOI 2010] 内部白点 - 扫描线 - 树状数组的更多相关文章

  1. BZOJ 1818: [Cqoi2010]内部白点 扫描线+树状数组

    问题转化为求每一个极长横线段与极长纵线段的交点个数. 这个东西用扫描线+树状数组维护一下就可以了. code: #include <cstdio> #include <algorit ...

  2. 【BZOJ1818】[Cqoi2010]内部白点 扫描线+树状数组

    [BZOJ1818][Cqoi2010]内部白点 Description 无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点).每秒钟,所有内部白点同时变 ...

  3. Bzoj1818: [Cqoi2010]内部白点 && Tyvj P2637 内部白点 扫描线,树状数组,离散化

    1818: [Cqoi2010]内部白点 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 704  Solved: 344[Submit][Status] ...

  4. 【BZOJ1818】[CQOI2010]内部白点(树状数组,扫描线)

    [BZOJ1818][CQOI2010]内部白点(树状数组,扫描线) 题面 BZOJ 题解 不难发现\(-1\)就是在搞笑的. 那么对于每一行,我们显然可以处理出来最左和最右的点,那么等价于我们在横着 ...

  5. 【BZOJ】1818: [Cqoi2010]内部白点(树状数组+离散+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1818 这一题一开始我就看错了,bzoj的那个绝对值109简直坑人,应该是10^9,我直接写了个暴力. ...

  6. BZOJ 1818 内部白点(离散化+树状数组)

    此题就是1227 的弱化版. 画个图或者稍微证明一下就能够知道,一定不会超过一次变换. 那么我们只需要统计有多少个白点会变黑,换句话说就是有多少个白点上下左右都有黑点. 离散化横坐标,因为没有黑点在的 ...

  7. BZOJ_1818_[Cqoi2010]内部白点 _扫描线+树状数组

    BZOJ_1818_[Cqoi2010]内部白点 _扫描线+树状数组 Description 无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点).每秒钟 ...

  8. BZOJ 4009: [HNOI2015]接水果 (整体二分+扫描线 树状数组)

    整体二分+扫描线 树状数组 具体做法看这里a CODE #include <cctype> #include <cstdio> #include <cstring> ...

  9. FZU 2225 小茗的魔法阵 扫描线+树状数组

    这个题和一个CF上的找"Z"的题差不多,都是扫描线+树状数组 从右上角的主对角线开始扫描,一直扫到左下角,每次更新,右延伸等于该扫描线的点,注意在其所在的树状数组更新就好了 时间复 ...

随机推荐

  1. opencv-resize()放缩函数简介

    主要介绍函数resize(); 图像缩放的效果图如下: 主程序代码及函数解释如下所示: /******************************************************* ...

  2. Hibernate基础增删改查语法

    1.创建好Hibernate项目,创建好实体类和测试类,如果不会创建Hibernate项目的同学,点此处:http://www.cnblogs.com/zhaojinyan/p/9336174.htm ...

  3. 自学oracle数据库

    1.因为自己要自学oracle数据库,所以就上网查了一下资料,总结了一下. 在以下连接有自学oracle的一下资料 博文中不让加入一些有广告的网站,请谅解,如有需要评论我私发. 2.学习Oracle的 ...

  4. HTML5表单及其验证

    随笔- 15 文章- 1 评论- 115 HTML5表单及其验证   HTML表单一直都是Web的核心技术之一,有了它我们才能在Web上进行各种各样的应用.HTML5 Forms新增了许多新控件及其A ...

  5. 安装模块时报错“error: Microsoft Visual C++ 14.0 is required…”

    安装pymssql时报错:在安装的过程中遇到了“error: Microsoft Visual C++ 14.0 is required…” 解决办法: 进入https://www.lfd.uci.e ...

  6. video control

    function VideoControls(option){ this.id = option.videoId; this.videoId = document.getElementsByTagNa ...

  7. Linux基础命令---uniq

    uniq 将文件中重复出现的行删除,结果送到标准输出或者指定文件.在使用uniq指令之前,必须使用sort对内容进行排序,否则没有效果.如果没有选项,则将匹配的行合并到第一个匹配项. 此命令的适用范围 ...

  8. webview相关知识

    标签类 1.Web App 建议用的样式 用于覆盖 WebView 默认的样式,使得 App 看起来更像原生的 App,——“不露出马脚” /* document.documentElement.st ...

  9. 利用iOS中Safari浏览器创建伪Web App

    在safari浏览器里有一个“添加到主屏幕”选项,我们可以用来创建伪Web App,下面来了解一下iOS中Safari的私有属性 第一步设置Web App的主屏幕图标: 有两种属性值apple-tou ...

  10. Codeforce 791A - Bear and Big Brother

    Bear Limak wants to become the largest of bears, or at least to become larger than his brother Bob. ...