题解
尽量使用只扣敌方血量的武器进行攻击,也就是在[1, n]范围内不是2~m倍数的武器。使用二进制枚举容斥求,注意只求素数的。
题目数据保证没有平局情况,最后判断敌方血量减去不是2~m倍数的数量是否大于自身血量。
m=1则所有武器都会让自己掉血(不知道是题面写错了还是我理解有问题)。总复杂度O(T*π(m)*2^π(m))。
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
int p[] = { 2, 3, 5, 7, 11, 13, 17, 19 }; //只留质数
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--)
{
ll a, b, n, m; //m=1表示所有攻击都会扣自己血
scanf("%lld%lld%lld%lld", &a, &b, &n, &m);
ll s = 0; //扣除敌方
int k = upper_bound(p, p + 8, m) - p;
for (int i = 1; i < (1 << k); ++i)
{
ll mul = 1, cnt = 0;
for (int j = 0; j < k; ++j)
if (i & (1 << j))
mul *= p[j], cnt++;
s += n / mul * (cnt & 1 ? 1 : -1);
}
s = n - s; //不是倍数的能直接扣
n -= s;
b -= s;
if (a > 0 && a > b)
printf("Yes\n");
else
printf("QAQ\n");
}
return 0;
}