QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#287084#5316. Xavier is Learning to Countbear0131AC ✓439ms10728kbC++144.6kb2023-12-19 15:36:282023-12-19 15:36:28

Judging History

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

  • [2023-12-19 15:36:28]
  • 评测
  • 测评结果:AC
  • 用时:439ms
  • 内存:10728kb
  • [2023-12-19 15:36:28]
  • 提交

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);
		int p = (int)lhs.size() - 1;
		while(p >= 0 && lhs[p] == 0) --p;
		lhs.resize(p+1);
		return lhs;
	}
	vi polymul(vi lh, vi rh){
		vi ret(N);
		rep(i, N) ret[i] = mul(lh[i], rh[i]);
		return ret;
	}
};

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], f1[6], f2[6];
vector<ll> ans;
vi ans1, ans2;
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];
	}

	P1.initN((int)f[5].size());
	P2.initN((int)f[5].size());
	for(int i = 1; i <= 5; ++i) f1[i] = f[i], P1.dft(f1[i]);
	for(int i = 1; i <= 5; ++i) f2[i] = f[i], P2.dft(f2[i]);

	ans.clear(), ans1.clear(), ans2.clear();
	has.clear();
	dfs(0, -1);
	ans1.resize(P1.N), ans2.resize(P1.N);

	for(auto it = has.begin(); it != has.end(); ++it){
		vi cnt = it->first;
		vi cur1(P1.N, 1), cur2(P2.N, 1);
		rep(j, (int)cnt.size()) cur1 = P1.polymul(cur1, f1[cnt[j]]), cur2 = P2.polymul(cur2, f2[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, P1.N) cout << cur1[j] << " ";
		//cout << ": " << coef << "\n";
		rep(j, P1.N) P1.umul(cur1[j], (coef >= 0 ? coef : coef + M1)), P2.umul(cur2[j], (coef >= 0 ? coef : coef + M2));
		rep(j, P1.N) P1.uadd(ans1[j], cur1[j]), P2.uadd(ans2[j], cur2[j]);
	}
	P1.dft(ans1, 1), P2.dft(ans2, 1);
	ans.resize(P1.N);
	rep(j, P1.N) ans[j] = calc(ans1[j], ans2[j]);

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

int main(){
	//freopen("5316.in", "r", stdin);
	//freopen("5316.out", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);

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

	//cerr << 1. * clock() / CLOCKS_PER_SEC << "\n";

	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 439ms
memory: 10728kb

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:

ok 637443 lines