UVA??? 考试 Exam

本来这篇题解是想在中考前写的,但是直到考前都没调出来,原因是 pow() 的精度感人。

由于 x0(modab),令 c=xab,答案即 abcn无序三元组 (a,b,c) 数量。

考虑把无序转成有序,即 abc,但显然会算少,分 4 种情况讨论:

  • a=b=c=k,合法的有 (k,k,k),对答案的贡献为 1
  • a=b=k<c,合法的有 (k,k,c),(k,c,k),(c,k,k),贡献为 3
  • a<b=c=k,合法的有 (k,k,c),(k,c,k),(c,k,k),贡献为 3
  • a<b<c,合法的有 (a,b,c),(a,c,b),(b,a,c),(b,c,a),(c,a,b),(c,b,a),贡献为 6

我们只需要统计 4 中情况每种的数量,乘上对应的贡献加起来即可。

  • a=b=c=kabcnkn3,方案数为 n3
  • a=b=k<c,枚举 k(显然不会超过 n3),k<cnk2,方案数为 k=1n3nk2k
  • a<b=c=k,枚举 akna,方案数为 a=1n3naa
  • a<b<c,枚举 a,bcnab,方案数为 a=1n3b=a+1nanabb

不难计算出复杂度 O(Tn23)

#include <bits/stdc++.h>
#define int long long
using namespace std;

namespace vbzIO {
	char ibuf[(1 << 20) + 1], *iS, *iT;
	#if ONLINE_JUDGE
	#define gh() (iS == iT ? iT = (iS = ibuf) + fread(ibuf, 1, (1 << 20) + 1, stdin), (iS == iT ? EOF : *iS++) : *iS++)
	#else
	#define gh() getchar()
	#endif
	#define mt make_tuple
	#define mp make_pair
	#define fi first
	#define se second
	#define pc putchar
	#define pb push_back
	#define ins insert
	#define era erase
	#define bg begin
	#define rbg rbegin
	typedef tuple<int, int, int> tu3;
	typedef pair<int, int> pi;
	inline int rd() {
		char ch = gh();
		int x = 0;
		bool t = 0;
		while (ch < '0' || ch > '9') t |= ch == '-', ch = gh();
		while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gh();
		return t ? ~(x - 1) : x;
	}
	inline void wr(int x) {
		if (x < 0) {
			x = ~(x - 1);
			putchar('-');
		}
		if (x > 9)
			wr(x / 10);
		putchar(x % 10 + '0');
	}
}
using namespace vbzIO;

int n, k, t;

int calc() {
	int res = k;
	for (int i = 1; i <= k; i++) {
		res += max((int)sqrt(n / i) - i, 0ll) * 3;
		res += max(n / (i * i) - i, 0ll) * 3;
		for (int j = i + 1; i * j * (j + 1) <= n; j++) 
			res += (n / (i * j) - j) * 6;
	}
	return res;
}

int cl(int x) {
    int res = -1, l = 1, r = 1e6;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (mid * mid * mid <= x) l = mid + 1, res = mid;
        else r = mid - 1;
    }
    return res;
}

signed main() {
	while (~scanf("%lld", &n)) {
		k = cl(n);
		printf("Case %lld: %lld\n", ++t, calc());
	}
	return 0;
}

upd : 补充一下复杂度证明,但是不太严谨。

不难发现复杂度主要是在第 4 部分,为 T(n)=i=1n3(nii)

后面那个 i 可以直接扔出来变成 n3,考虑:

i=1n3ni=ni=1n31in1n13x12dx=O(n12n16)=O(n23)

所以复杂度就大概 O(n23) 了。

posted @   Arghariza  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示
主题色彩