题目链接:http://codeforces.com/problemset/problem/799/C
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define read(x,y) scanf("%d%d",&x,&y)
#define ll long long
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
const int maxn =1e5+5;
const int mod=1e9+7;
const int ub=1e6;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
/*
题目大意:给定两种货币,和每种的上限用额,
然后给定两种商品的具体信息,每种价值都对应着一个权值,
要求选出两个,使其权值和最大。
这道题真是让我受教育了,
在拿到这种决策最优性问题时经常容易犯糊涂或者是想到了复杂的算法,用线段树维护来维护去,
又一次被树状数组打脸了,这要在比赛中这不是跟别人差了十万八千里了。
首先我悟道了这样一个东西,题目中要求选择一个二元组,
那么对于每个物品来求解另一个物品组成的最优解是可以覆盖所有最优解候选项的。(按时间线扫描)
题目意思中,两个物品可以是同一组的也可以是不同组的,
那么用树状数组进行最优维护时就要注意,
能不能把所有的情况都涵盖进去。
对于扫描到的任何一种物品,都有两种决策,一种是在维护好的本类组中选出最优,一种是在另一种中选出最优,两边维护下即可。
如果维护出有意义的答案就更新最终答案。
*/
///数据域
int n,c,d;
int x,y,ans;
char s[10];
///树状数组
int tree1[maxn<<1],tree2[maxn<<1];
int lowbit(int x)
{
return x&(-x);
}
void add(int *t,int x,int d)
{
for(;t[x]=max(t[x],d),x<maxn;x+=lowbit(x));
}
int sum(int* t,int x)
{
int ret=0;
for(;x>0;ret=max(ret,t[x]),x-=lowbit(x));
return ret;
}
int main()
{
scanf("%d%d%d",&n,&c,&d);
ans=0;
for(int i=0;i<n;i++)
{
scanf("%d%d%s",&x,&y,s);
int ret=0;
if(s[0]=='C')
{
ret=sum(tree2,d);
if(y>c) continue;
ret=max(ret,sum(tree1,c-y));
add(tree1,y,x);
}
else
{
ret=sum(tree1,c);
if(y>d) continue;///确保不会出现错误情况。
ret=max(ret,sum(tree2,d-y));
add(tree2,y,x);
}
if(ret) ans=max(ans,ret+x);
}
printf("%d\n",ans);
return 0;
}