2020牛客暑期多校训练营(第七场)

B Mask Allocation

题意:

就是将 n ∗ m n∗m nm 个口罩分成 k k k 份,使得可以从中挑出 n n n 组,每组口罩数一样多;也可以从中挑出 m m m 组,每组口罩一样多,最后输出的字典序要最大。

2020牛客暑期多校训练营(第七场)_第1张图片

AC代码:

const int N = 1e5 + 10;
const ll mod = 1e9 + 7;
int a[N];
int main()
{
	int T;
	sd(T);
	while (T--)
	{
		int n, m;
		sdd(n, m);
		int cnt = 0;
		while (n != 0 && m != 0)
		{
			if (n < m)
			{
				int t = n;
				n = m;
				m = t;
			}
			int tmp = m;
			while (tmp--)
				a[++cnt] = m;
			n -= m;
		}
		pd(cnt);
		rep(i, 1, cnt)
			printf("%d%c", a[i], i == cnt ? '\n' : ' ');
	}
	return 0;
}

D Fake News

题意:

打表找规律,只有 1 1 1 24 24 24 第符合的。

AC代码:

int main()
{
    int t;
    sd(t);
    while (t--)
    {
        sld(n);
        if (n == 1||n==24)
            puts("Fake news!");
        else
            puts("Nobody knows it better than me!");
    }
}

H Dividing(数论分块)

题意:

用题给的三种操作,问 N , K N , K N,K 范围内有多少个不同二元组。

找找规律会发现对于每个 k k k n % k = = 0 n\%k == 0 n%k==0 的所有点都可以凑到,因为这些点都是可以通过 ( 1 , k ) (1,k) (1,k) 进行 n k nk nk 操作得到, n % k = = 1 n\%k == 1 n%k==1也如此,因为这些点都是可以通过 ( 1 , k ) (1,k) (1,k) 进行 n + k n+k n+k 操作得到。
那么就每次累加 n 1 + n 2 + n 3 + . . . + n k + n − 1 1 + n − 1 2 + n − 1 3 + . . . + n − 1 k \frac{n}{1}+\frac{n}{2}+\frac{n}{3}+...+ \frac{n}{k}+\frac{n-1}{1}+\frac{n-1}{2}+\frac{n-1}{3}+...+ \frac{n-1}{k} 1n+2n+3n+...+kn+1n1+2n1+3n1+...+kn1 , 统计完去掉 k = 1 k=1 k=1 时候重合的,加上除 k > = 2 k>=2 k>=2 时候每次漏的 1 1 1 即是答案。利用整数分块算法解答。

AC代码:

const int N = 2e7 + 50;
const int mod = 1e9 + 7;
ll n, k;
ll ans;

void cal(ll n, ll k)
{
	for (ll l = 2, r; l <= k; l = r + 1)
	{
		r = n / l;
		r = min(r, n);
		if (r)
			r = n / r;
		else
			r = k;
		r = min(r, k);
		int len = (r - l + 1) % mod;
		int tmp = (n / l) % mod;
		ans = (ans + len * 1ll * tmp % mod) % mod;
	}
}

int main()
{
	sldd(n, k);
	ans = (n + k - 1) % mod;
	cal(n, k);
	n--;
	cal(n, k);
	pld(ans);
	return 0;
}

你可能感兴趣的:(牛客)