QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#286379#5316. Xavier is Learning to Countbear0131TL 0ms0kbC++144.0kb2023-12-17 19:33:402023-12-17 19:33:41

Judging History

你现在查看的是最新测评结果

  • [2023-12-17 19:33:41]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2023-12-17 19:33:40]
  • 提交

answer

#include<bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (n); ++i)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef array<int, 3> ai3;
const ll inf = 0x3f3f3f3f3f3f3f3fll;
const double pi = acos(-1);
inline void chmax(int &a, int b){ (b>a) ? (a=b) : 0; }
inline void chmin(int &a, int b){ (b<a) ? (a=b) : 0; }

template<const int Mod> struct poly{
	inline int sign(int a){ return (a&1) ? (Mod-1) : 1; }
	inline void uadd(int &a, int b){ a += b-Mod; a += (a>>31) & Mod; }
	inline void usub(int &a, int b){ a -= b, a += (a>>31) & Mod; }
	inline void umul(int &a, int b){ a = (int)(1ll * a * b % Mod); }
	inline int add(int a, int b){ a += b-Mod; a += (a>>31) & Mod; return a; }
	inline int sub(int a, int b){ a -= b, a += (a>>31) & Mod; return a; }
	inline int mul(int a, int b){ a = (int)(1ll * a * b % Mod); return a; }
	int qpow(int b, ll pr){ int ret = 1; while(pr){ if(pr&1) umul(ret, b); umul(b, b), pr >>= 1; } return ret; }
	int to[525252], w[525252];
	int N, bl;
	void dft(vi &a, bool idft = 0){
		a.resize(N);
		rep(i, N) if(to[i] < i) swap(a[i], a[to[i]]);
		for(int len = 0; len < bl; ++len) for(int l = 0; l < N; l += (1<<len)<<1)
			for(int i = 0; i < (1<<len); ++i){
				int x = a[l|i], y = mul(a[l|(1<<len)|i], w[i<<(bl-len-1)]);
				a[l|i] = add(x, y), a[l|(1<<len)|i] = sub(x, y);
			}
		if(idft){
			for(int i = 1; i < N-i; ++i) swap(a[i], a[N-i]);
			int invn = qpow(N, Mod-2);
			rep(i, N) umul(a[i], invn);
		}
	}
	void initN(int _n){
		bl = 0;
		while((1<<bl) < _n) ++bl;
		N = (1<<bl);
		w[0] = 1, w[1] = qpow(3, (Mod-1) / N);
		for(int i = 2; i <= N; ++i) w[i] = mul(w[i-1], w[1]);
		rep(i, N) to[i] = (to[i>>1]>>1) + ((i&1)<<(bl-1));
	}
	vi conv(vi lhs, vi rhs){
		initN((int)lhs.size() + (int)rhs.size());
		lhs.resize(N), rhs.resize(N);
		dft(lhs), dft(rhs);
		rep(i, N) umul(lhs[i], rhs[i]);
		dft(lhs, 1);
		while(lhs.back() == 0) lhs.pop_back();
		return lhs;
	}
};

const int M1 = 998244353, M2 = 1004535809;
poly<M1> P1;
poly<M2> P2;
const int I1 = P2.qpow(M1, M2 - 2), I2 = P1.qpow(M2, M1-2);

int p;
vi f[6];
vector<ll> ans;
int v[6];
const int coef_mp[] = {1, 1, -1, 2, -6, 24}, fact[] = {1, 1, 2, 6, 24, 120};
ll calc(int v1, int v2){
	//cout << "calc " << v1 << " " << v2 << " = " << (ll)(((__int128)v1 * I2 * M2 + (__int128)v2 * I1 * M1) % (1ll * M1 * M2)) << "\n";
	return (ll)(((__int128)v1 * I2 * M2 + (__int128)v2 * I1 * M1) % (1ll * M1 * M2));
}
map<vi, int> has;
void dfs(int i, int mx){
	if(i >= p){
		vi cnt(mx+1, 0);
		rep(j, p) ++cnt[v[j]];
		++has[cnt];
		return ;
	}
	for(v[i] = 0; v[i] <= mx+1; ++v[i])
		dfs(i+1, max(mx, v[i]));
}
int n;
void solve(int cc){
	cin >> n >> p;
	f[1].clear();
	rep(i, n){ int a; cin >> a; while((int)f[1].size() < a+1){ f[1].push_back(0); } ++f[1][a]; }
	for(int i = 2; i <= 5; ++i){
		f[i].resize(i * ((int)f[1].size() - 1) + 1);
		rep(j, (int)f[1].size()) f[i][i*j] = f[1][j];
	}

	ans.clear();
	has.clear();
	dfs(0, -1);

	for(auto it = has.begin(); it != has.end(); ++it){
		vi cnt = it->first;
		vi cur1 = (vi){1}, cur2 = (vi){1};
		rep(j, (int)cnt.size()) cur1 = P1.conv(cur1, f[cnt[j]]), cur2 = P2.conv(cur2, f[cnt[j]]);
		int coef = it->second;
		rep(j, (int)cnt.size()) coef *= coef_mp[cnt[j]];
		//rep(j, (int)cnt.size()){ cout << cnt[j] << " "; } cout << ": ";
		//rep(j, (int)cur1.size()) cout << cur1[j] << " ";
		//cout << ": " << coef << "\n";
		rep(j, (int)cur1.size()) P1.umul(cur1[j], (coef >= 0 ? coef : coef + M1)), P2.umul(cur2[j], (coef >= 0 ? coef : coef + M2));
		if((int)ans.size() < (int)cur1.size()) ans.resize((int)cur1.size());
		rep(j, (int)cur1.size()) (ans[j] += calc(cur1[j], cur2[j])) %= (1ll * M1 * M2);
	}

	cout << "Case #" << cc << ": \n";
	rep(i, (int)ans.size()) if(ans[i] > 0) cout << i << ": " << ans[i] / fact[p] << "\n";
	cout << "\n";
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int T;
	cin >> T;
	for(int cc = 1; cc <= T; ++cc) solve(cc);

	return 0;
}

详细

Test #1:

score: 0
Time Limit Exceeded

input:

114
46 2
54 50 45 63 14 96 25 34 26 92 57 68 72 11 7 21 30 47 59 85 60 6 36 22 88 56 39 48 97 70 58 10 9 77 29 18 93 62 44 37 17 4 43 67 78 19
57 5
45 81 24 97 93 35 95 58 36 25 27 31 1 62 65 38 20 9 71 49 55 78 18 86 70 23 87 74 46 17 98 42 2 85 28 19 63 84 16 67 66 37 22 26 14 69 61 57 43 8 32 75 ...

output:

Case #1: 
10: 1
11: 1
13: 2
14: 1
15: 2
16: 2
17: 2
18: 2
19: 1
20: 2
21: 3
22: 1
23: 3
24: 3
25: 4
26: 3
27: 3
28: 5
29: 4
30: 3
31: 4
32: 5
33: 4
34: 2
35: 5
36: 6
37: 3
38: 3
39: 5
40: 7
41: 4
42: 2
43: 8
44: 5
45: 4
46: 5
47: 7
48: 7
49: 4
50: 5
51: 8
52: 5
53: 6
54: 9
55: 8
56: 7
57: 6
58: 7
59...

result: