P3431 [POI2005]AUT-The Bus【树状数组+离散化】【二维偏序】

题意:

n*m的范围内有k个点
1 n 1 0 9 , 1 m 1 0 9 1\leq n \leq 10^9 ,1\leq m \leq 10^9 1n109,1m109
你从(0, 0)出发到(n,m) 每次你只能往上或往右移动,求经历的路径最大点权值

思路:

也就是说我们要让点经历的 x i x i + 1 , y i y i + 1 x_i \leq x_{i+1},y_i \leq y_{i+1} xixi+1,yiyi+1
也就是二维偏序,求最大前缀和
先对y坐标排序,离散化
树状数组,区间修改 改成 维护最大前缀和 区间查询 改成查询最大前缀和
然后再对点根据x坐标排序

AC_code:

/* Algorithm: Author: anthony1314 Creat Time: Time Complexity: */
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5+5;
int bit[MAXN];
int cnt = 0;
struct node {
	int x, y, val;
} p[MAXN];
bool cmp1(node aa, node bb) {
	return aa.y < bb.y;
}
bool cmp2(node aa, node bb) {
	if(aa.x == bb.x) {
		return aa.y < bb.y;
	}
	return aa.x < bb.x;
}
int lowbit(int x) {
	return x&(-x);
}
void add(int i,int x) {
	while(i<=cnt) {
// bit[i]+=x;
		bit[i] = max(bit[i], x);
		i+=lowbit(i);
	}
}
int sum(int i) {
	int s=0;
	while(i>0) {
// s+=bit[i];
		s = max(s, bit[i]);
		i-=lowbit(i);
	}
	return s;
}

int main() {
	int n, m, k;
	cin>>n>>m>>k;
	for(int i = 1; i <= k; i++) {
		scanf("%d %d %d", &p[i].x, &p[i].y, &p[i].val);
	}
	//对y排序 离散化
	sort(p+1, p+1+k, cmp1);
	int now = p[1].y;
	p[1].y = ++cnt;
	for(int i = 2; i <= k; i++) {
		if(p[i].y != now) {
			now = p[i].y;
			p[i].y = ++cnt;
		} else {
			p[i].y = cnt;
		}
	}
	// 对x排序 再对y排序 左下优先
	sort(p+1, p+1+k, cmp2);
	int res;
	int ans = 0;//当前的最大前缀和
	for(int i = 1; i <= k; i++) {
		res = sum(p[i].y)+p[i].val;
		//cout<<res<<endl;
		add(p[i].y, res);
		ans = max(res, ans);
	}
	cout<<ans<<endl;

	return 0;
}
全部评论

相关推荐

11-28 17:58
门头沟学院 Java
美团 JAVA开发 n×15.5
牛客786276759号:百度现在晋升很难的 而且云这块的业务没美团好 你看百度股价都跌成啥样了
点赞 评论 收藏
分享
安静的垂耳兔在泡澡:ks已经第八次投递了,它起码挂了还让你再投,不错了
点赞 评论 收藏
分享
沉淀一会:1.同学你面试评价不错,概率很大,请耐心等待; 2.你的排名比较靠前,不要担心,耐心等待; 3.问题不大,正在审批,不要着急签其他公司,等等我们! 4.预计9月中下旬,安心过节; 5.下周会有结果,请耐心等待下; 6.可能国庆节前后,一有结果我马上通知你; 7.预计10月中旬,再坚持一下; 8.正在走流程,就这两天了; 9.同学,结果我也不知道,你如果查到了也告诉我一声; 10.同学你出线不明朗,建议签其他公司保底! 11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务