CF1184B1 The Doctor Meets Vader (Easy) 题解
题面。
大佬的题解写的太好了,这里给出不同于大佬的做法。
思路
读入后,将 \(b\) 数组按照关键字 \(d\) 从小到大排序,并用前缀和数组记录下前 \(i\) 个 \(d\) 的总和。在对每个 \(a_i\) 进行查询时,二分找出第一个 \(a_i\) 不能攻打的城市 \(l\),此时说明前 \(l-1\) 座城市对于 \(a_i\) 来说都能攻打,所得到的黄金数量就是 \(q[l-1]\)。这里的变量 \(b\),\(d\),\(a\) 均与题目翻译对应。
想要纯暴力的做法是行不通的,即使是四秒的时限,别问我怎么知道的。
代码
PS:自从用了 VsCode 后格式变得有点奇怪,看着有点难受。
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<stdio.h>
#define ll long long
#define inf 0x3f3f3f3f
#define fr(i , a , b) for(ll i = a ; i <= b ; ++i)
#define fo(i , a , b) for(ll i = a ; i >= b ; --i)
using namespace std;
inline char gchar()
{
static char buf[1000000] , *p1 = buf , *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 1000000 , stdin) , p1 == p2) ? EOF : *p1++;
}
inline ll read()
{
ll x = 0 , f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
ll s , b , a[100005];
ll q[100005];
struct node
{
ll d , g;
bool operator < (const node &x) const
{
return d < x.d;
}
}str[100005];
signed main()
{
s = read();
b = read();
fr(i , 1 , s)
{
a[i] = read();
}
fr(i , 1 , b)
{
str[i].d = read();
str[i].g = read();
q[i] = q[i - 1] + str[i].g;
}
sort(str + 1 , str + b + 1);
fr(i , 1 , b)
{
q[i] = q[i - 1] + str[i].g;
}
fr(i , 1 , s)
{
ll l = 1 , r = b , mid;
while(l <= r)
{
mid = (l + r) >> 1;
if(str[mid].d <= a[i])
{
l = mid + 1;
}
else
{
r = mid - 1;
}
}
printf("%lld " , q[l - 1]);
}
system("pause");
return 0;
}
- 一个好的指挥官不会背叛他的军队,无论代价是什么。
- 一个更好的指挥官知道当他想背叛他的军队时,什么时候应该伪装。
- 一个最好的指挥官精明地确立自己的绝对领导,并引领着人民走向更好的未来。