[Codeforces 975C] [Valhalla Siege] [前缀和+二分]
链接:
http://codeforces.com/problemset/problem/975/C
题意:
n个士兵站成一排,每个士兵有ai点hp,q回合内,每回合有ki支箭,每支箭伤害为1。
士兵从最左边开始挡箭,hp为0即会死亡,某回合内士兵全部死亡,则本回合末全部满血复活。
q次询问,每回合末还活着的士兵有多少?
思路:
计算hp的前缀和数组sum,二分搜索arrCnt+ki;
如果士兵全部死亡则置arrCnt=0;
代码:
1 #include<cstdio>
2 #include<iostream>
3
4 using namespace std;
5
6 typedef long long LL;
7
8 const int MAXN=2e5+10;
9
10 LL hp[MAXN],arr[MAXN],sum[MAXN];
11
12 int bSearch(int l,int r,LL x);
13
14 int main(void)
15 {
16 int n,q;
17 cin>>n>>q;
18
19 cin>>hp[0];
20 sum[0]=hp[0];
21 for (int i=1;i<n;i++) {
22 scanf("%lld",&hp[i]);
23 sum[i]=sum[i-1]+hp[i];
24 }
25 for (int i=0;i<q;i++) {
26 scanf("%lld",&arr[i]);
27 }
28
29 int cur;
30 LL arrCnt=0;
31 for (int i=0;i<q;i++) {
32 arrCnt+=arr[i];
33 cur=bSearch(0,n-1,arrCnt);
34
35 if (cur==-1) {
36 cout<<n<<endl;
37 arrCnt=0;
38 } else {
39 cout<<n-cur<<endl;
40 }
41 }
42 return 0;
43 }
44
45 int bSearch(int l,int r,LL x)
46 {
47 int left=l,right=r;
48 while (left<right) {
49 int mid=left+(right-left)/2;
50 if (sum[mid]>x) {
51 right=mid;
52 } else {
53 left=mid+1;
54 }
55 }
56 if (sum[left]>x) {
57 return left;
58 } else {
59 return -1;
60 }
61 }
二十余年如一梦,此身虽在堪惊