出题人题解 | #Tachibana Kanade Loves Game#

Tachibana Kanade Loves Game

https://ac.nowcoder.com/acm/problem/23368

原题解链接:https://ac.nowcoder.com/discuss/173818

简单的数学题。

首先,你需要注意到题面种“若存在ji j \mid i,则会使的你的血量减少 11”这句话的含义,是“如果存在,那么血量减11”,因此无论有多少个jj 满足ji j \mid i ,你的血量都只会减少1 1

考虑k=0k=0时,你开局就死了,因此答案一定为QAQQAQ

考虑k=1k=1,即你不能选择任何会触发反击魔咒的武器,即你能够选择的数,不是[2,m][2,m]中任何一个数的倍数。当 m=1m = 1 时,注意到我们不需要考虑任何情形。否则,考虑任意一个数d[2,m]d\in [2,m],若其不为素数,则其一定有真素因子pp,若pxp \nmid x,则dxd \nmid x,因此我们只需要考虑[2,m][2,m]的全体素数构成的集合,不妨记其为Pm\mathbb P_m ,则显然答案为: i=1njPm[ji]\sum^n_{i=1} \prod_{j\in \mathbb P_m} [j \nmid i]然而这个式子难以处理,因此我们重新考虑后面的谓词表达式。记然而这个式子难以处理,因此我们重新考虑后面的谓词表达式。记P=jPmjP=\prod_{j\in \mathbb P_m} j,那么如果,那么如果jPm\forall j \in \mathbb P_m,都有,都有jxj \nmid x,那么一定有,那么一定有(P,x)=1(P, x)=1,反之亦然。

结论1:jPm\forall j \in \mathbb P_m,都有jxj \nmid x 的充要条件为(P,x)=1(P,x) = 1

证明:必要性是显然的。

充分性:假设(P,x)=d1(P,x) = d\ne 1 ,那么一定有dP,dxd \mid P, d\mid x,设P=p1p2psP=p_1p_2\cdots p_s,则一定存在ii使得d=pid = p_i ,即pixp_i \mid x,与条件矛盾。

因此,我们便可以计算出我们能造成的总伤害AAA=i=1n[(P,i)=1]=i=1nd(P,i)μ(d)=dPμ(d)id1=dPPdμ(d)A=\sum^n_{i=1} [(P,i) = 1]=\sum^n_{i=1} \sum_{d \mid (P,i)} \mu(d) = \sum_{d\mid P} \mu(d) \sum_{i \mid d} 1 = \sum_{d \mid P} \left\lfloor\frac Pd\right\rfloor \mu(d) 预处理出[2,m][2,m]μ(x)\mu(x),这个式子就可以通过枚举PP的因子计算完成。由于PPπ(m)\pi(m)个不同素数的乘积,因此它的因子个数为2π(m)2^{\pi(m)}。时间复杂度O(T2π(m))O(T2^{\pi(m)}),考虑到π(n)nlogn\pi(n) \sim \frac{n}{\log n}可以轻松通过此题

考虑k>1k > 1,我们会发现,我们可以使用k1k-1次会触发反击魔咒的武器,因此总伤害即为A=min{A+k1,n}A'=\min \{A+k-1, n\}(要对 nnminmin的原因是每种武器只能用11次,最多只能造成n n 点伤害)

最后,我们只需要判定AqA'\geqslant q输出YesYes,否则输出NoNo即可

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cassert>

constexpr int maxn = 10000000;
constexpr int mod = 20050117;

long long mu[maxn], b[maxn], pri[] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29}, cnt, d[10005], size, T;
int table[] = {0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8 };

inline char nc() 
{
    static char buf[1000000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}

inline long long read() 
{
    long long res = 0;
    char ch = nc();
    while (!isdigit(ch)) ch = nc();
    while (isdigit(ch)) res = res * 10 + ch - 48, ch = nc();
    return res;
}

int main() 
{
    d[0] = d[1] = 1;
    mu[0] = mu[1] = 1;
    for (int i = 1; i <= 8; ++i) 
	{
        for (int k = 1; k <= size; ++k) 
		{
            d[k + size] = d[k] * pri[i];
            mu[d[k + size]] = -mu[d[k]];
        }
        d[size = (size << 1) + 1] = pri[i];
        mu[pri[i]] = -1;
    }
    T = read();
    while (T--) 
	{
    	long long k = read(), q = read(), n = read(), m = read();
		if (k == 0) 
		{
			puts("QAQ");
			continue; 
    	}
    	
		long long s, x, y, ans = 0;
        x = 1, y = n, s = m;
        s = table[s];
        --x;
        size = (1 << s) - 1;
        for (int i = 0; i <= size; ++i)
            ans = (ans + mu[d[i]] * (y / d[i] - x / d[i]));
        ans = std::min(n, ans + k - 1);
        if (ans >= q) puts("Yes");
        else puts("QAQ");
    }
    return 0;
}
全部评论

相关推荐

小谷围鸡肉卷阿姨:+1,腾子投完一动不动
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务