问卡常
  • 板块灌水区
  • 楼主lvvd
  • 当前回复12
  • 已保存回复12
  • 发布时间2024/11/1 14:54
  • 上次更新2024/11/1 18:39:33
查看原帖
问卡常
517291
lvvd楼主2024/11/1 14:54

已经不知道是第几次因为代码常数大被卡掉了。

但是我不明白我的代码的常数总是很大,我自我感觉我打的很多代码也不算很丑/lh

问一个实际一点的问题吧,下面是我今天的 NOIP 模拟赛的一道题的代码,后面一段是我的一个同学的代码,我认为我实现得是比他精细的,实际上我 T 了但他没有,有没有好心人指出我的代码哪里常数过大了?

我的代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
unsigned long long rp;
ll ans, sum, x, tmp, lsh[500005];
int n, m, cnt[500005], r[61][500005], R[500005][61];
unordered_map<ll, int> id;
int main() {
#ifdef Lopera
	freopen("game/ex_game3.in", "r", stdin);
	// freopen("game.out", "w", stdout);
	// freopen("game.err", "w", stderr);
#else
	freopen("game.in", "r", stdin);
	freopen("game.out", "w", stdout);
#endif
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> rp;
	while(rp--) {
		cin >> n;
		m = 0;
		id.clear();
		for(int i = 1; i <= n; ++i) {
			cin >> x;
			if(!id.count(x)) {
				id[x] = m;
				lsh[m] = x, cnt[m] = 1;
				++m;
			}
			else ++cnt[id[x]];
		}
		for(int j = 0; j < 61; ++j) {
			id.clear();
			x = 0;
			for(int i = 0; i < m; ++i) {
				tmp = (lsh[i] & ((1ll << j) - 1));
				if(!id.count(tmp)) r[j][id[tmp] = x++] = 0;
				r[j][R[i][j] = id[tmp]] += cnt[i];
			}
		}
		ans = n * (n - 1ll) * (n - 2ll) / 6;
		for(int i = 0; i < m; ++i) {
			if(cnt[i] == 1) continue;
			sum = -cnt[i];
			for(int j = 0; j < 61; ++j) {
				if(j & 1) sum -= r[j][R[i][j]];
				else sum += r[j][R[i][j]];
			}
			ans -= cnt[i] * (cnt[i] - 1ll) * (cnt[i] - 2ll) / 6ll + cnt[i] * (cnt[i] - 1ll) / 2ll * sum;
		}
		cout << ans << '\n';
	}
	cerr << (double)clock() / CLOCKS_PER_SEC;
	return 0;
}

我同学的代码

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll IINF = 1e18;
const int N = 5e5 + 5, M = 2e7 + 5;
int flg[105][105][105];
int sg(int i, int j, int k) {
	int a[3] = {i, j, k};
	sort(a, a + 3);
	i = a[0], j = a[1], k = a[2];
	if(flg[i][j][k] != -1) return flg[i][j][k];
	set<int> f;
	for(int l = 1; l <= (j - i) / 2; l++) f.insert(sg(i + l, j - l, k));
	for(int l = 1; l <= (k - i) / 2; l++) f.insert(sg(i + l, j, k - l));
	for(int l = 1; l <= (k - j) / 2; l++) f.insert(sg(i, j + l, k - l));
	for(int l = 0; ; l++) if(!f.count(l)) return flg[i][j][k] = l;
}
void baoli() {
	memset(flg, -1, sizeof flg);
	for(int i = 1; i <= 10; i++) for(int j = i + 1; j <= 10; j++) for(int k = j + 1; k <= 10; k++) {
		if(!sg(i, j, k)) printf("%d %d %d\n", i, j, k);
	}
}
int n, T, cnt;
ll a[N], lsh[N], ans;
unordered_map<ll, int> mp;
int tr[M][2], vis[M][2], siz[M];
void insert(ll x) {
	int p = 0;
	for(int i = 0; i <= 60; i++) {
		int opt = (x >> i) & 1;
		if(vis[p][opt] != T) vis[p][opt] = T, tr[p][opt] = ++cnt, siz[cnt] = 0;
		siz[p = tr[p][opt]]++;
	}
}
void query(ll x, ll res) {
	int p = 0, fa = 0;
	for(int i = 0; i <= 60; i++) {
		int opt = (x >> i) & 1;
		if(vis[p][opt] != T) vis[p][opt] = T, tr[p][opt] = 0;
		if(vis[p][1 - opt] != T) vis[p][1 - opt] = T, tr[p][1 - opt] = 0;
		if((i & 1)) ans += res * siz[tr[fa][1 - ((x >> i - 1) & 1)]];
		fa = p, p = tr[p][opt];
	}
	ans += 1ll * siz[p] * (siz[p] - 1) / 2 * (siz[p] - 2) / 3;
}
void solve() {
	ans = cnt = 0, T++;
	cin>>n;
	for(int i = 1; i <= n; i++) cin>>a[i], insert(a[i]);
	sort(a + 1, a + n + 1);
	a[n + 1] = -1; 
	for(int i = 1, lst = 1; i <= n; i++) if(a[i] != a[i + 1]) {
		ll tmp = i - lst + 1;
		query(a[i], tmp * (tmp - 1) / 2);
		lst = i + 1;
	}
	cout<<1ll * n * (n - 1) / 2 * (n - 2) / 3 - ans<<'\n';
}
int main() {
	cnt = 0;
	freopen("game.in", "r", stdin);
	freopen("game.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int t; cin>>t;
	while(t--) solve();
	cerr<<clock() * 1.0 / CLOCKS_PER_SEC<<'\n';
	return 0;
}
2024/11/1 14:54
加载中...