Codeforces Round #413 C. Fountains (线段树的创建、查询、更新)
vj题目链接:
https://vjudge.net/contest/235444#problem/F
题意:
有 n 个待建的喷泉,每个的建造代价为pi coins或者pi diamonds(coins 和 diamonds 不可互相兑换),每个喷泉的魅力为bi。问在原有c coins和d diamonds 的情况下,选择两个喷泉,使得在能支付代价的前提下,魅力值最高?如果拥有的钱不足以支付两个喷泉,就输出0,否则输出两个喷泉的最大b值的和。
1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<cstring>
5 using namespace std;
6 int maxn=100010;
7 int tree[2][400010];
8 int b,p;
9 char ch;
10 void build(int t,int rt,int l,int r)//新建二叉搜索树
11 {
12 if(l==r)
13 {
14 tree[t][rt]=0;
15 return ;
16 }
17 int mid=(l+r)>>1;
18 build(t,rt<<1,l,mid);
19 build(t,(rt<<1)+1,mid+1,r);
20 }
21 int query(int t,int rt,int l,int r,int ql,int qr)//查询二叉搜索树
22 {
23 if(ql<=l&&qr>=r)
24 {
25 return tree[t][rt];
26 }
27 int mid=(l+r)>>1;
28 int ll=0,rr=0;
29 if(ql<=mid)
30 {
31 ll=query(t,rt<<1,l,mid,ql,qr);
32 }
33 if(qr>mid)
34 {
35 rr=query(t,(rt<<1)+1,mid+1,r,ql,qr);
36 }
37 return max(ll,rr);
38 }
39 void update(int t,int rt,int l,int r,int q,int v)//更新二叉搜索树
40 {
41 if(l==r)
42 {
43 tree[t][rt]=max(tree[t][rt],v);
44 return ;
45 }
46 int mid=(l+r)>>1;
47 if(q<=mid)
48 {
49 update(t,rt<<1,l,mid,q,v);
50 }
51 if(q>mid)
52 {
53 update(t,(rt<<1)+1,mid+1,r,q,v);
54 }
55 tree[t][rt]=max(tree[t][rt<<1],tree[t][(rt<<1)+1]);
56
57 }
58 int main()
59 {
60 int n,c,d;
61 cin>>n>>c>>d;
62 build(0,1,0,c);
63 build(1,1,0,d);
64 int maxc=0,maxd=0;
65 int ans=0;
66 for(int i=0;i<n;i++)
67 {
68 cin>>b>>p>>ch;
69 if(ch=='C')
70 {
71 if(p<=c)
72 {
73 maxc=max(maxc,b);
74 int p1=c-p;
75 int b1=query(0,1,0,c,0,p1);
76 cout<<b1<<endl;
77 if(b1!=0)
78 {
79 ans=max(ans,b1+b);
80 }
81 update(0,1,0,c,p,b);
82 }
83 }
84 else if(ch=='D')
85 {
86 if(p<=d)
87 {
88 maxd=max(maxd,b);
89 int p2=d-p;
90 int b2=query(1,1,0,d,0,p2);
91 if(b2!=0)
92 {
93 ans=max(ans,b2+b);
94 }
95 update(1,1,0,d,p,b);
96 }
97 }
98 }
99 if(maxc&&maxd)
100 ans = max(ans,maxc+maxd);
101 cout<<ans;
102 return 0;
103 }