超级马里奥

题目描述
超级玛丽现在又面临着一系列新的难关,他目前所在的 R 星球包含着 n 个城
堡,他现在正在城堡 1 中,而他要按照顺序依次通过每个城堡。
在第 2~n 个城堡中,有的潜伏着一头怪兽,而有的城堡里有一位公主。
在通关了超级玛丽变态版之后,马里奥现在的水平已经达到了可以秒杀所有
小怪的境界,在面对怪物的时候,他可以选择是否杀死他,如果干掉他,他可以
得到一定数量的金币,当然他也可以选择放可怜的怪物一条生路,但是这样他就
不能得到金币。
而面对公主,马里奥可能不会太淡定,如果马里奥在遇到某位公主之前杀死
的怪物数量达到了一个某个给定的值,这位公主就会爱慕这位英雄,而马里奥也
不会拒绝她的好意,马里奥将会马上终止他的旅程希望与这位公主幸福地生活下
去。
但是只有最后一个城堡 n 中的公主才是公主的真身,其余的公主都是最终
Boss 的假身,但是可怜的 mario 并不知道这一点,如果他被 Boss 引诱到了危险
的 E 星球后果将不堪设想。只有操控 mario 的你才能帮他完成最终的任务——和
真正的公主过上幸福的生活。相信聪明的你不仅可以让 mario 完成最终任务,还
能与此同时最大化 mario 旅程中得到的金币数。
输入格式
第一行一个整数 n。
接下来 n-1 行,分别描述了第 2~n 个城堡的情况。
若第 i 个城堡中有一只怪兽,那么该行以字母 d 开头,接下来一个正整数 c
表示杀死这头怪物能够得到的金币。
若第 i 个城堡中有一位公主,那么该行以字母 p 开头,接下来一个正整数 b
表示如果 mario 在遇到这位公主之前杀死了不少于 b 只怪物,这位公主就会爱慕
mario。
输出格式
如果马里奥不能完成他的任务,输出一行一个-1,否则输出马里奥的最大收
益。
输入样例 1
6d 10
d 12
p2
d1
p2
输出样例 1
13
输入样例 2
6
d 10
d 12
p2
d1
p3
输出样例 2
-1
数据规模
30%的数据,n<=2000。
另外 30%的数据,max{b}<=50。
100%的数据,2<=n<=200000,max{c}<=10000,max{b}<=200000,保证城堡
n 中一定是一位公主。

处理出一个怪物在哪两个公主中间

打掉一个怪物,那么之后能打的怪物又少一个

能打的怪物是后面的最小的公主限制

那么打掉一个怪,后面的所有公主限制都会减1

所以贪心,按金币数排序

然后线段树维护最小值

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 struct ZYYS
 8 {
 9   int val,nxt;
10 }a[200001];
11 int c[800001],lazy[800001],n,b[200001],cnt,tot,sum,ans;
12 bool cmp(ZYYS a,ZYYS b)
13 {
14   return a.val>b.val;
15 }
16 void pushup(int rt)
17 {
18   c[rt]=min(c[rt<<1],c[rt<<1|1]);
19 }
20 void build(int rt,int l,int r)
21 {
22   if (l==r)
23     {
24       c[rt]=b[l];
25       return;
26     }
27   int mid=(l+r)>>1;
28   build(rt<<1,l,mid);
29   build(rt<<1|1,mid+1,r);
30   pushup(rt);
31 }
32 void pushdown(int rt)
33 {
34   if (lazy[rt])
35     {
36       c[rt<<1]+=lazy[rt];
37       c[rt<<1|1]+=lazy[rt];
38       lazy[rt<<1]+=lazy[rt];
39       lazy[rt<<1|1]+=lazy[rt];
40       lazy[rt]=0;
41     }
42 }
43 int query(int rt,int l,int r,int L,int R)
44 {
45   if (l>=L&&r<=R)
46     {
47       return c[rt];
48     }
49   pushdown(rt);
50   int mid=(l+r)>>1,s=2e9;
51   if (L<=mid) s=min(s,query(rt<<1,l,mid,L,R));
52   if (R>mid) s=min(s,query(rt<<1|1,mid+1,r,L,R));
53   pushup(rt);
54   return s;
55 }
56 void update(int rt,int l,int r,int L,int R,int d)
57 {
58   if (l>=L&&r<=R)
59     {
60       c[rt]+=d;
61       lazy[rt]+=d;
62       return;
63     }
64   int mid=(l+r)>>1;
65   pushdown(rt);
66   if (L<=mid) update(rt<<1,l,mid,L,R,d);
67   if (R>mid) update(rt<<1|1,mid+1,r,L,R,d);
68   pushup(rt);
69 }
70 int main()
71 {int i,x;
72   char word[5];
73   cin>>n;
74   memset(c,127/2,sizeof(c));
75   for (i=2;i<=n;i++)
76     {
77       scanf("%s",word);
78       scanf("%d",&x);
79       if (word[0]=='d') a[++cnt]=(ZYYS){x,tot+1};
80       else b[++tot]=x;
81     }
82   sum=b[tot];b[tot]=200000;
83   sort(a+1,a+cnt+1,cmp);
84   build(1,1,tot);
85   for (i=1;i<=cnt;i++)
86     {
87       int t=query(1,1,tot,a[i].nxt,tot);
88       if (t>1)
89     {
90       ans+=a[i].val;
91       sum--;
92       update(1,1,tot,a[i].nxt,tot,-1);
93     }
94     }
95   if (sum>0)
96   cout<<-1;
97   else cout<<ans;
98 }

 

posted @ 2018-03-19 15:40  Z-Y-Y-S  阅读(359)  评论(0编辑  收藏  举报