[HDOJ4022]Bombing(离散化+stl)
2016-05-12 19:44
375 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4022
一个图上有n个点,之后m个操作,每次操作一行或者一列。使得这一行或者这一列的点全部消除。每次操作输出每次消除的点的个数。
思路:
因为数据范围很大,刚开始想的是离散化后维护各行各列的点数,但是发现这样离线的做法只能维护当前状态,更新成了一个难题。后来在思考有没有一个方法,可以在不超过数据范围的情况下,在O(lgn)的限制内维护所有线上的坐标。想来想去,一开始想用map<int, vector<int>>的,但是vector扫描是O(n)的。那就要考虑一个非线性结构,最后想到了红黑树。还是保存重复元素的那个——std::multiset<int>。
所以这道题就变成了一道水题了。
一个图上有n个点,之后m个操作,每次操作一行或者一列。使得这一行或者这一列的点全部消除。每次操作输出每次消除的点的个数。
思路:
因为数据范围很大,刚开始想的是离散化后维护各行各列的点数,但是发现这样离线的做法只能维护当前状态,更新成了一个难题。后来在思考有没有一个方法,可以在不超过数据范围的情况下,在O(lgn)的限制内维护所有线上的坐标。想来想去,一开始想用map<int, vector<int>>的,但是vector扫描是O(n)的。那就要考虑一个非线性结构,最后想到了红黑树。还是保存重复元素的那个——std::multiset<int>。
所以这道题就变成了一道水题了。
#include <algorithm> #include <iostream> #include <iomanip> #include <cstring> #include <climits> #include <complex> #include <fstream> #include <cassert> #include <cstdio> #include <bitset> #include <vector> #include <deque> #include <queue> #include <stack> #include <ctime> #include <set> #include <map> #include <cmath> using namespace std; #define fr first #define sc second #define pb(a) push_back(a) #define Rint(a) scanf("%d", &a) #define Rll(a) scanf("%I64d", &a) #define Rs(a) scanf("%s", a) #define FRead() freopen("in", "r", stdin) #define FWrite() freopen("out", "w", stdout) #define Rep(i, n) for(int i = 0; i < (n); i++) #define For(i, a, n) for(int i = (a); i < (n); i++) #define Cls(a) memset((a), 0, sizeof(a)) #define Full(a) memset((a), 0x7f7f, sizeof(a)) const int maxn = 100010; int n, m; int x[maxn], y[maxn]; int hx[maxn], hxcnt; int hy[maxn], hycnt; int sx[maxn], sy[maxn]; map<int, multiset<int> > xx; map<int, multiset<int> > yy; multiset<int>::iterator it; inline bool scan_d(int &num) { char in;bool IsN=false; in=getchar(); if(in==EOF) return false; while(in!='-'&&(in<'0'||in>'9')) in=getchar(); if(in=='-'){ IsN=true;num=0;} else num=in-'0'; while(in=getchar(),in>='0'&&in<='9'){ num*=10,num+=in-'0'; } if(IsN) num=-num; return true; } int getid(int* h, int hcnt, int x) { return lower_bound(h, h+hcnt, x) - h; } int main() { // FRead(); int c, d; while(~scanf("%d%d", &n, &m) && n + m) { Cls(sx); Cls(sy); xx.clear(), yy.clear(); Rep(i, n) { scan_d(x[i]); scan_d(y[i]); hx[i] = x[i]; hy[i] = y[i]; xx[x[i]].insert(y[i]); yy[y[i]].insert(x[i]); } sort(hx, hx+n); sort(hy, hy+n); hxcnt = unique(hx, hx+n) - hx; hycnt = unique(hy, hy+n) - hy; Rep(i, n) { sx[getid(hx, hxcnt, x[i])]++; sy[getid(hy, hycnt, y[i])]++; } Rep(i, m) { scan_d(c); scan_d(d); if(c == 0) { printf("%d\n", xx[d].size()); for(it = xx[d].begin(); it != xx[d].end(); it++) { yy[*it].erase(d); } xx[d].clear(); sx[getid(hx, hxcnt, d)] = 0; } else { printf("%d\n", yy[d].size()); for(it = yy[d].begin(); it != yy[d].end(); it++) { xx[*it].erase(d); } sy[getid(hy, hycnt, d)] = 0; yy[d].clear(); } } printf("\n"); } return 0; }
相关文章推荐
- CentOS卸载OpenJDK
- 18大经典数据挖掘算法小结
- 基于Hadoop的数据仓库Hive 学习指南
- 25个Java机器学习工具&库
- C++ auto_ptr智能指针的用法
- 求自定类型元素的最大值
- HDOJ 1045 Fire Net同 ZOJ 1002
- 可变形部件模型DPM和HOG特征for行人检测Discriminatively trained deformable part models
- 实验三 进程调度模拟程序
- Sqlite数据库
- hibernate事务介绍
- 操作系统c实现银行家算法
- 在活动中不显示标题 --3
- eclipse/intellij idea 远程调试hadoop 2.6.0
- uva208
- [线段树合并]
- kafka环境
- 【操作系统】实验三 进程调度模拟程序 截止提交时间:2016.5.12
- 合并两个有序的链表
- fastImageCache解析:来自bang同学,非常棒!