超级马里奥
题目描述
超级玛丽现在又面临着一系列新的难关,他目前所在的 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 }