CodeForces - 799C Fountains

Fountains
题 意:Alice想建两座喷泉,现在有n座喷泉,每座喷泉的美丽值为pi,价格为ci个coins或者di个diamonds。两种货币不可以互换。现在Alice有c个coins和d个diamonds。问alice建造的两座喷泉最大的美丽值为多少?

数据范围:

2<=n<=1e5
0<=c,d<=1e5
1<=ci,di<=1e5

输入样例:

3 7 6
10 8 C   //代表是用货币c买 d代表是用货币d买
4 3 C  
5 6 D

输出样例:

9

思 路:首先可以确定有三种情况,第一种DC这种情况很简单找到最大的。第二种情况DD,这种情况要找到两个加起来最大的,枚举一个ai,用线段树取维护区间最大值,去找令一个aj。CC同样的原理。 复杂度O(nlgn)可以过去。

#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn = 1e5+5;
int sum1[maxn<<2],sum2[maxn<<2];
struct node{
    int x,y;
}a[maxn],b[maxn];
int n,c,d;
void PushUp(int rt){
    sum1[rt] = max(sum1[rt<<1],sum1[rt<<1|1]);
    sum2[rt] = max(sum2[rt<<1],sum2[rt<<1|1]);
}
void build(int l,int r,int rt){
    sum1[rt] = 0;
    sum2[rt] = 0;
    if(l == r) return;
    int m = (l+r)/2;
    build(lson);
    build(rson);
    PushUp(rt);
}
void update(int pos,int val,int flag,int l,int r,int rt){
    if(l == r){
        if(flag){
            sum1[rt] = max(sum1[rt],val);
        }else{
            sum2[rt] = max(sum2[rt],val);
        }
        return ;
    }
    int m = (l+r)/2;
    if(pos <= m) update(pos,val,flag,lson);
    else update(pos,val,flag,rson);
    PushUp(rt);
}
int query(int L,int R,int flag,int l,int r,int rt){
    if(L<=l && r<=R){
        if(flag){
            return sum1[rt];
        }else{
            return sum2[rt];
        }
    }
    int m = (l+r)/2,ans = 0;
    if(L<=m) ans = max(ans,query(L,R,flag,lson));
    if(R >m) ans = max(ans,query(L,R,flag,rson));
    return ans;
}
int main(){
    while(~scanf("%d %d %d",&n,&c,&d)){
        int num1 = 0,num2 = 0;
        int val,cost;char s[3];
        int MAX1 = 0,MAX2 = 0,ans = 0;
        for(int i=0;i<n;i++){
            scanf("%d %d %s",&val,&cost,s);
            if(s[0] == 'C' && cost <= c){
                a[num1].x = val;
                a[num1++].y = cost;
                MAX1 = max(MAX1,val);
            }else if(s[0] == 'D' && cost <= d){
                b[num2].x = val;
                b[num2++].y = cost;
                MAX2 = max(MAX2,val);
            }
        }
        if(MAX1!=0 && MAX2 !=0){
            ans = max(ans,MAX1+MAX2);
        }
        build(0,100000,1);
        for(int i=0;i<num1;i++){
            int current = c-a[i].y;
            int res = query(0,current,1,0,100000,1);
            if(res!=0){
                ans = max(ans,res+a[i].x);
            }
            update(a[i].y,a[i].x,1,0,100000,1);
        }
        for(int i=0;i<num2;i++){
            int current = d-b[i].y;
            int res = query(0,current,0,0,100000,1);
            if(res!=0){
                ans = max(ans,res+b[i].x);
            }
            update(b[i].y,b[i].x,0,0,100000,1);
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37129433/article/details/81809089
799
今日推荐