Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains

该博客主要探讨了一种动态规划问题,涉及到区间最大值查询的数据结构优化。通过构建二叉树并使用最大堆,实现了在更新成本的同时查询最大价值。博客还介绍了如何在C++中实现这个算法,并在不同情况下优化查询效率。
摘要由CSDN通过智能技术生成
#include <iostream>  
#include <stdio.h>  
#include <string.h>   
#include <stack>  
#include <queue>   
#include <map>  
#include <set>  
#include <vector>  
#include <math.h>  
#include <bitset>  
#include <algorithm>  
#include <climits>
using namespace std;
// #define int long long
const int N=1e5+10;
const int mod= 998244353;
struct node{
    int l,r,val;
}tr[3][N<<2];
struct node2{
	int val,cost;
};
int now;
const int M=-1e9;
vector<node2> v[2];
int n,c,d;
void pushup(int p){
    tr[now][p].val=max(tr[now][p<<1].val,tr[now][p<<1|1].val);
}
void build(int p,int l,int r){
    tr[now][p]={l,r,M};
    if(l==r){
    	tr[now][p].val=v[now][l-1].val;
    	return ;
    }
    int mid=(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    pushup(p);
}
void change(int pos,int p,int val){
    if(tr[now][p].l==tr[now][p].r){tr[now][p].val=val;return ;}
    int mid=tr[now][p].l+tr[now][p].r>>1;
    if(pos<=mid) change(pos,p<<1,val);
    else change(pos,p<<1|1,val);
    pushup(p);
}
int query(int p,int l,int r){
    if(tr[now][p].l>=l&&tr[now][p].r<=r){
        return tr[now][p].val;
    }
    int res=-1e9;
    int mid=tr[now][p].l+tr[now][p].r>>1;
    if(mid>=l) res=max(res,query(p<<1,l,r));
    if(mid+1<=r) res=max(res,query(p<<1|1,l,r));
    return res;
}
bool cmp(node2 a,node2 b){
	return a.cost<b.cost;
}
int res=0;
void sol(int x){
    int pos=v[x].size()-1;
    int C=(x==0?c:d);
	if(v[x].size()>=2){
		// cout<<v[x].size()<<endl;
		for(int i=0;i<v[x].size();i++){
			if(C>=v[x][i].cost){
				int left=C-v[x][i].cost;
				change(i+1,1,M);
                while(pos>=0&&v[x][pos].cost>left) pos--;
                if(pos==-1) return;
				res=max(v[x][i].val+query(1,1,pos+1),res);
                change(i+1,1,v[x][i].val);
			}
		}
	}
}
int main(){
	scanf("%d%d%d",&n,&c,&d);
	int val1=-1,val2=-1;
	for(int i=1;i<=n;i++){
		int b,p;char ch;scanf("%d%d",&b,&p);cin>>ch;
		if(ch=='C') {
			v[0].push_back({b,p});
			if(c>=p) val1=max(val1,b);
		}
		else{
			v[1].push_back({b,p});
			if(d>=p) val2=max(val2,b);
		}
	}
	if(val1!=-1&&val2!=-1) res=val1+val2;
	sort(v[0].begin(),v[0].end(),cmp);
	sort(v[1].begin(),v[1].end(),cmp);
	now=0;
    if(v[0].size()>=2) build(1,1,v[0].size()),sol(0);
	now=1;
    if(v[1].size()>=2) build(1,1,v[1].size()),sol(1);
    cout<<res<<endl;
	// now=0;cout<<query(1,1,v[now].size());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值