codeforces 799C(线段树区间更新)
来源:互联网 发布:网络大电影制作 编辑:程序博客网 时间:2024/06/18 05:10
C. Fountains
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Arkady plays Gardenscapes a lot. Arkady wants to build two new fountains. There are n available fountains, for each fountain its beauty and cost are known. There are two types of money in the game: coins and diamonds, so each fountain cost can be either in coins or diamonds. No money changes between the types are allowed.
Help Arkady to find two fountains with maximum total beauty so that he can buy both at the same time.
Input
The first line contains three integers n, c and d (2 ≤ n ≤ 100 000, 0 ≤ c, d ≤ 100 000) — the number of fountains, the number of coins and diamonds Arkady has.
The next n lines describe fountains. Each of these lines contain two integers bi and pi (1 ≤ bi, pi ≤ 100 000) — the beauty and the cost of the i-th fountain, and then a letter “C” or “D”, describing in which type of money is the cost of fountain i: in coins or in diamonds, respectively.
Output
Print the maximum total beauty of exactly two fountains Arkady can build. If he can’t build two fountains, print 0.
Examples
input
3 7 6
10 8 C
4 3 C
5 6 D
output
9
input
2 4 5
2 5 C
2 1 D
output
0
input
3 10 10
5 5 C
5 5 C
10 11 D
output
10
Note
In the first example Arkady should build the second fountain with beauty 4, which costs 3 coins. The first fountain he can’t build because he don’t have enough coins. Also Arkady should build the third fountain with beauty 5 which costs 6 diamonds. Thus the total beauty of built fountains is 9.
In the second example there are two fountains, but Arkady can’t build both of them, because he needs 5 coins for the first fountain, and Arkady has only 4 coins.
题意:有两种货币,然后有n件东西,每件东西有一个美丽值,和一个价格,价格只能是两种货币中的任意一种,然后给你这个人现在有的两种货币的数量,让你买两个东西,使他们的美丽值和最大,如果不能够买到两件东西,则输出0.
解题思路:初一看,有点像背包什么的,仔细一分析,发现是个线段树区间更新,我们分析可得,一共就三种情况,第一种情况,两件东西,一件来自于C货币类型的物品,一件来自于D货币类型的物品,第二种情况,两件东西都来自于C货币类型的物品,第三种情况,两件东西都来自于D货币类型的物品,然后我们三种情况都考虑下,取最大值就行。对于第一种情况,最好办,贪心的找到一个最大美丽值,且能够被买下的就行。第二种情况和第三种情况是一样的,我们就一起分析,也就是问题变成了在一堆物品中找两个物品,在他们的总价格不超过我们手中的货币情况下使他们的美丽值和最大。因为只需要找两个,我们从第一个物品扫到最后一个物品就行,中间我们用线段树维护一个价格为x的最大可以加上的美丽值就行,具体思路看代码。
#include<bits/stdc++.h>using namespace std;const int maxn = 1e5 + 10;int n,c,d;struct node{ int b; int p;};struct tree{ int l; int r; int value; int add;}Tree[4*maxn];node Node1[maxn];node Node2[maxn];int cnt1;//cint cnt2;//dvoid add(int b,int p,char ch){ if(ch == 'C') { node nx; nx.b = b; nx.p = p; Node1[++cnt1] = nx; } else { node nx; nx.b = b; nx.p = p; Node2[++cnt2] = nx; }}void pushDown(int i){ int f1 = i<<1; int f2 = f1 + 1; Tree[f1].value = max(Tree[f1].value,Tree[i].add); Tree[f1].add = max(Tree[f1].add,Tree[i].add); Tree[f2].value = max(Tree[f2].value,Tree[i].add); Tree[f2].add = max(Tree[f2].add,Tree[i].add); Tree[i].add = -1;}void build(int i,int l,int r){ Tree[i].l = l; Tree[i].r = r; Tree[i].value = -1; Tree[i].add = -1; if(l == r) { return; } int f = i<<1; int mid = (l + r)>>1; build(f,l,mid); build(f + 1,mid + 1,r);}void update(int i,int l,int r,int value){ if(Tree[i].l == l&&Tree[i].r == r) { Tree[i].value = max(Tree[i].value,value); if(l == r) { Tree[i].add = -1; } else { Tree[i].add = max(Tree[i].add,value); } return; } if(Tree[i].add != -1) pushDown(i); int f = i<<1; if(r <= Tree[f].r) update(f,l,r,value); else if(l >= Tree[f + 1].l) update(f + 1,l,r,value); else { update(f,l,Tree[f].r,value); update(f + 1,Tree[f + 1].l,r,value); }}int query(int i,int l,int r){ if(Tree[i].l == l&&Tree[i].r == r) return Tree[i].value; if(Tree[i].add != -1) pushDown(i); int f = i<<1; if(r <= Tree[f].r) return query(f,l,r); else if(l > Tree[f].r) return query(f + 1,l,r); else return max(query(f,l,Tree[f].r),query(f + 1,Tree[f + 1].l,r));}void init(){ cnt1 = 0; cnt2 = 0;}int main(){ while(~scanf("%d%d%d",&n,&c,&d)) { init(); int B,P; char C; for(int i = 1; i <= n; i++) { cin>>B>>P>>C; add(B,P,C); } int Max = 0; int ans1 = -1; int ans2 = -1; for(int i = 1; i <= cnt1; i++) { if(c >= Node1[i].p) ans1 = max(ans1,Node1[i].b); } for(int i = 1; i <= cnt2; i++) { if(d >= Node2[i].p) { ans2 = max(ans2,Node2[i].b); } } if(ans1 != -1&&ans2 != -1) Max = max(Max,ans1 + ans2); build(1,1,100000); for(int i = 1; i <= cnt1; i++) { B = Node1[i].b; P = Node1[i].p; int x = query(1,P,P); if(x != -1) { Max = max(Max,B + x); } if(c - P >= 1) update(1,1,c - P,B); } build(1,1,100000); for(int i = 1; i <= cnt2; i++) { B = Node2[i].b; P = Node2[i].p; int x = query(1,P,P); if(x != -1) { Max = max(Max,B + x); } if(d - P >= 1) update(1,1,d - P,B); } printf("%d\n",Max); } return 0;}
- codeforces 799C(线段树区间更新)
- Codeforces 52C (线段树区间更新)
- CodeForces 52C Circular RMQ (区间更新线段树)
- Codeforces 272C(线段树区间更新)@
- CodeForces 52C Circular RMQ(区间循环线段树,区间更新,区间求和)
- CodeForces 52C Circular RMQ (区间更新线段树)
- Codeforces 444C DZY Loves Colors 线段树区间更新
- CodeForces - 272C Dima and Staircase (线段树区间更新)
- CodeForces 52C Circular RMQ (线段树的区间更新+lazy tag)
- codeforces 52C Circular RMQ(线段树区间更新)【模板】
- CodeForces 46D Parking Pot(线段树区间更新)
- 线段树(区间更新)codeforces 292E Copying Data
- CodeForces 315B(线段树+区间更新)
- CF#52 C Circular RMQ (线段树区间更新)
- Codeforces 272C Dima and Staircase (线段树区间更新 或 线性扫)
- CodeForces 272C-Dima and Staircase-线段树区间更新-RMQ
- Codeforces 276C Little Girl and Maximum Sum(线段树的区间更新)
- 线段树(单点更新+区间更新)
- 【python】-- NameError: name 'reload' is not defined
- PHP学习笔记——加增自定义函数库
- idea 常用快捷键
- Hadoop 运行模式之单机模式
- 2017广东工业大学程序设计竞赛决赛 C题 爬楼梯(简单递推)
- codeforces 799C(线段树区间更新)
- mnist数据集转成图片 Python 实现
- sessionStorage 、localStorage 和 cookie
- Javascript代码风格
- JAVA8为Arrays类增加的工具方法
- React Native组件之Button
- 夜间模式切换
- 行为型模式之职责链模式(Chain of responsibility)
- 蓝桥杯 格子中输出