牛客练习赛43 F Tachibana Kanade Loves Game 数学 容斥

版权声明:若您发现我的博文中有纰漏或有其他想法,诚挚希望您能与我讨论。QQ1171297065 https://blog.csdn.net/qq_40758751/article/details/89068714

链接:https://ac.nowcoder.com/acm/contest/548/F
来源:牛客网
 

题目描述


立华奏是一个天天打比赛的萌新。

省选将至,萌新立华奏深知自己没有希望进入省队,因此开始颓废。她正在颓废一款名为《IODS 9102》的游戏。

在游戏中,立华奏拥有 k 点血量,而她的对手拥有 q 点血量。当她的血量变为 0 时,游戏便结束了;同理,如果对方的血量变为 0,立华奏就获胜了。在立华奏手中,有 n 种武器,编号分别为1,2,⋯,n1,2,⋯,n,每一种武器在使用后,都能让对方受到 1 点伤害,且此后不得再次使用这个武器。同时,对方拥有m−1m−1 种反击魔咒,编号分别为 2,3,4,⋯,m2,3,4,⋯,m(如果 m = 1,则可认为此时不具有反击魔咒)。如果立华奏在使用第 i 种武器攻击对方时,对方恰好有编号为 j 的魔咒,且j∣ij∣i, 那么立华奏会受到 1 点伤害(注意此时,攻击仍然是有效的,即对方的血量仍然会减少 1),同时对方也可以再次使用这个反击魔咒。

由于立华奏是个萌新,因此对方保证不会主动攻击立华奏 。

现在,立华奏想要知道,自己是否存在一种攻击方案,使得自己取得胜利。

输入描述:

输入包含多组数据。

输入的第一行包含一个整数 T,表示数据组数。

接下来 T 行,每行包含四个整数 k, q, n, m,描述一组数据。

输出描述:

输出 T 行,每行描述一组数据的解。如果本组数据中,立华奏存在必胜策略,则输出 Yes,否则输出 QAQ。

你可以认为数据保证不会出现平局的情形。

示例1

输入

复制

5
0 23333 2333333 5
1 1999999999 29999999999999 9
1 998244353998244 12345678 9
1 3 3 4
1 5 6 7

输出

复制

QAQ
Yes
QAQ
QAQ
QAQ

说明

对于第一组样例,立华奏开始就死掉了,因此答案为QAQ

对于第二组样例,你只需要使用所有的不含{2,3,4,5,6,7,8,9}因子的武器即可,显然在 29999999999999 内存在这些武器

对于第三组样例,立华奏的武器只有12345678个,但她的对手血量更多,显然她不可能取胜

对于第四组样例,你的血量为1,代表你不能使用会触发反击魔咒的武器,答案为QAQ

对于第五组样例,与第四组样例是相同的

备注:

1⩽T⩽105,0⩽k⩽1018,0<q⩽1018,0⩽n⩽1018,1⩽m⩽20

x只要是2~m中素数的倍数就会使自身减血。所以我们可以把1~n分成2~m中素数的个数份集合,然后求集合的并集就是会造成减血的武器数目。

比如m=5 则2~m中素数为 2 3 5 则可以得到三个集合n/2 n/3 n/5只要利用容斥原理求出三个集合的并集即可。

使自身减血的武器个数为 n-n/2-n/3n-n/5+n/6+n/10+n/15-n/30

可以用dfs来求解改表达式

//#include<bits/stdc++.h>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <time.h>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define sdddd(x,y,z,k) scanf("%d%d%d%d", &x, &y, &z, &k)
#define sddd(x,y,z) scanf("%d%d%d", &x, &y, &z)
#define sdd(x,y) scanf("%d%d", &x, &y)
#define sd(x) scanf("%d", &x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
//#define mp make_pair
#define pb push_back
#define ms(x, y) memset(x, y, sizeof x)
#define MOD 10000
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 50000050;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
//typedef vector<ll> vec;
//typedef vector<vec> mat;
template <class T>
inline bool scan_d(T &ret) {
    char c; int sgn;
    if (c = getchar(), c == EOF) return 0;
    while (c != '-' && (c<'0' || c>'9')) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return 1;
}
int arr[30] = {0,0,1,2,2,3,3,4,4,4,4,5,5,6,6,6,6,7,7,8,8};
int prime[20] = {0,1,2,3,5,7,11,13,17,19,23};
ll n, m, k, q, t;
ll res;
void dfs(int i, int cnt, ll tot){
    if(prime[i+1] > m){
        if(cnt%2){
            res -= n/tot;
        }
        else{
            res += n/tot;
        }
        return;
    }
    dfs(i+1, cnt+1, tot*prime[i+1]);
    dfs(i+1, cnt, tot);
}

int main()
{
    //std::ios::sync_with_stdio(false);
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    scan_d(t);
    while(t--){
        res = 0;
        scan_d(k); scan_d(q); scan_d(n); scan_d(m);
        if(k == 0){
            puts("QAQ");
            continue;
        }
        else{
            dfs(1,0,1);
            //cout << res << "\n";
            if(res+k > q)
                puts("Yes");
            else
                puts("QAQ");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40758751/article/details/89068714