[BZOJ1537][POI2005]Aut- The Bus
1537: [POI2005]Aut- The Bus
Time Limit: 5 Sec Memory Limit: 64 MB Submit: 397 Solved: 272 [Submit][Status][Discuss]Description
Byte City 的街道形成了一个标准的棋盘网络 – 他们要么是北南走向要么就是西东走向. 北南走向的路口从 1 到 n编号, 西东走向的路从1 到 m编号. 每个路口用两个数(i, j) 表示(1 <= i <= n, 1 <= j <= m). Byte City里有一条公交线, 在某一些路口设置了公交站点. 公交车从 (1, 1) 发车, 在(n, m)结束.公交车只能往北或往东走. 现在有一些乘客在某些站点等车. 公交车司机希望在路线中能接到尽量多的乘客.帮他想想怎么才能接到最多的乘客.
Input
第一行三个数n, m 和 k – 表示北南走向的路的个数以及西东走向的路和乘客等车的站点的个数. ( 1 <= n <= 10^9, 1 <= m <= 10^9, 1 <= k <= 10^5). 接下来k 行每行描述一个公交站的信息.第 i + 1 行三个正整数 xi, yi 和 pi, 1 <= xi <= n, 1 <= yi <= m, 1 <= pi <= 10^6. 表示在(xi, yi) 有 pi 个乘客在等车. 每个路口在数据中最多出现一次,乘客总数不会超过1 000 000 000.
Output
一个数表示最多能接到的乘客数量.
Sample Input
8 7 11
4 3 4
6 2 4
2 3 2
5 6 1
2 5 2
1 5 5
2 1 1
3 1 1
7 7 1
7 4 2
8 6 2
4 3 4
6 2 4
2 3 2
5 6 1
2 5 2
1 5 5
2 1 1
3 1 1
7 7 1
7 4 2
8 6 2
Sample Output
11
当两个点$\left(x1,y1\right),\left(x2,y2\right)$满足$x1\le x2$且$y1\le y2$则第二个点可以由第一个点的车开到
所以先按照$x$为第一关键字$y$为第二关键字排序,然后每次查询最大值,然后加入这个状态
离散化后用树状数组维护即可
#include <cstdio> #include <cstring> #include <algorithm> char buf[10000000], *ptr = buf - 1; inline int readint(){ int n = 0; while(*++ptr < '0' || *ptr > '9'); while(*ptr <= '9' && *ptr >= '0') n = (n << 1) + (n << 3) + (*ptr++ & 15); return n; } const int maxn = 100000 + 10; inline void max(int &a, const int &b){ if(a < b) a = b; } int n, c[maxn] = {0}; int num[maxn], cnt; inline int Query(int pos){ int s = 0; for(int i = pos; i; i -= i & -i) max(s, c[i]); return s; } inline void Update(int pos, int val){ for(int i = pos; i <= cnt; i += i & -i) max(c[i], val); } struct Node{ int x, y, p; bool operator < (const Node &a) const{ return x == a.x ? y < a.y : x < a.x; } }no[maxn]; int main(){ buf[fread(buf, sizeof(char), sizeof(buf), stdin)] = 0; readint(); readint(); n = readint(); for(int i = 1; i <= n; i++){ no[i].x = readint(); num[i] = no[i].y = readint(); no[i].p = readint(); } std::sort(num + 1, num + n + 1); cnt = std::unique(num + 1, num + n + 1) - (num + 1); for(int i = 1; i <= n; i++) no[i].y = std::lower_bound(num + 1, num + cnt + 1, no[i].y) - num; std::sort(no + 1, no + n + 1); for(int t, i = 1; i <= n; i++){ t = Query(no[i].y); Update(no[i].y, no[i].p + t); } printf("%d\n", Query(cnt)); return 0; }