原题指路
题目大意
有
n
(
1
≤
n
≤
1
0
9
)
n(1 \leq n \leq 10^9)
n(1≤n≤109) 个士兵攻击魔法师,这些士兵初始分为
m
(
1
≤
m
≤
1
0
7
)
m(1 \leq m \leq 10^7)
m(1≤m≤107) 组,每组至少
1
1
1 人。
每一回合,每个存活的士兵会对魔法师造成
1
1
1 点伤害。之后魔法师选择一组士兵,击杀其中最多
k
(
1
≤
k
≤
1
0
7
)
k(1 \leq k \leq 10^7)
k(1≤k≤107) 人。
魔法师很聪明,总会采用最后策略。
如果士兵最终造成的最大总伤害不小于
x
(
1
≤
x
≤
1
0
13
)
x(1 \leq x \leq 10^{13})
x(1≤x≤1013),则输出“YES”和可能造成的最大总伤害 。否则输出“NO”。
题解
显然的,在魔法师一次就能消灭任意小组的情况下,在将其平均分成
m
m
m 个小组的情况是最优的,
一组大小为
x
+
k
x+k
x+k 的士兵可以分为一组大小为
x
x
x 的士兵和一组大小为
k
k
k 的士兵,
而除
k
k
k 外剩下的小组人数相等时是最优的,所以我们可以跑循环得出满足的
a
a
a 使得
a
k
+
m
x
=
n
(
x
<
k
)
ak+mx=n (x < k)
ak+mx=n(x<k)
然后通过一定的配对计算出答案,通过计算可知,
(
n
/
k
−
m
)
≤
a
≤
(
n
/
k
)
(n/k-m) \leq a \leq (n/k)
(n/k−m)≤a≤(n/k)。
代码
#include<bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
int n,m,a,x,k;
ll ans1;
void solve(ll x)
{
ll b=n-x*k;
ll y=b%m,c=m-y,d=b/m,sum=0;
sum+=(n+(n-x*k+k))*x/2; //x部分
sum+=((n-x*k)+(n-x*k-y*(d+1)+d+1))*y/2; //余数部分
sum+=((c*d)+(d))*c/2; //a部分
ans1=max(ans1,sum);
}
signed main()
{
scanf("%lld%lld%lld%lld",&n,&m,&k,&x);
for(ll r=n%k,p=n%k;p<=n&&p<=r+m*k;p+=k) //寻找满足条件的 a
solve((n-p)/k);
if(ans1<x)
puts("NO");
else
printf("YES %lld",ans1);
}