正睿二轮省选day1
期望:100+16+8
实际:0+16+8
T1:
最后的二分找每个1的位置写没了,本机上测爆longlong会到负数,但正睿的机子不是,判错了,直接爆0
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; const int N = 100010; const int mod = 998244353; const LL INF = 1e18 + 1; LL n, K; LL C[75][N], len[75]; inline int dec(int x, int y) { return x < y ? x - y + mod : x - y; } inline void add(int& x, int y) { x += y; if (x >= mod)x -= mod; } inline LL qpow(LL a, LL k, LL p = mod) { LL res = 1; while (k) { if (k & 1) res = res * a % mod; a = a * a % mod; k >>= 1; } return res; } inline LL check(LL n, LL m) { if (m >= 4) return n > len[m] ? INF : C[m][n]; else { __int128 c = 1; for (int i = 0; i < m; ++i) { c *= n - i, c /= i + 1; if (c > 1e18)return INF; } return c; } } int main() { int T; scanf("%d", &T); for (LL i = 4;; i++) { C[4][i] = i * (i - 1) / 2 * (i - 2) / 3 * (i - 3) / 4; if (C[4][i] > 1e18) { len[4] = i - 1; break; } } for (int i = 5; i <= 70; ++i) { for (LL j = i;; ++j) { C[i][j] = C[i - 1][j - 1] + C[i][j - 1]; if (C[i][j] > 1e18) { len[i] = j - 1; break; } } } while (T--) { scanf("%lld%lld", &n, &K); LL k = (sqrt(8 * n - 7) - 1) / 2; LL a = n - k * (k + 1) / 2; if (k - a == -1) { if (K == 1) printf("%d\n", dec(qpow(2, k + 1), 1)); else puts("-1"); } else if (k - a >= 61 || (1ll << (k - a)) >= K) { int ans = dec(qpow(2, k + 1), qpow(2, k + 1 - a)); if (k == a) printf("%d\n", ans); else { LL s = 0, i; __int128 c = 1; for (i = 0;; ++i) { if (c >= K || (s + c) >= K)break; s += c, c *= k - a - i, c /= i + 1; } K -= s, --K; for (LL j = i, lim = k - a - 1; j >= 1; --j) { LL lb = j - 1, rb = lim, mid, ret; if (j > 4) rb = min(rb, len[j]); while (lb <= rb) { mid = (lb + rb) >> 1; if (check(mid, j) <= K) lb = mid + 1, ret = mid; else rb = mid - 1; } lim = ret - 1, K -= check(ret, j); add(ans, qpow(2, ret)); } printf("%d\n", ans); } } else puts("-1"); } return 0; }
T2:
考场上看出来了,SAM模板题,但是我不会写,只写了暴力
#include<cstdio> #include<cstring> #include<vector> #include<map> #include<iostream> #include<algorithm> using namespace std; #define mp make_pair typedef long long LL; typedef pair<int, int> PII; const int N = 50010; map<PII, int> vis; struct String { int siz, last; string str; struct Node { int len, link; map<char, int> nex; Node() {} }; map<int, Node> st; void sam_extend(char c) { int cur = siz++; st[cur].len = st[last].len + 1; int p = last; while (p != -1 && !st[p].nex.count(c)) { st[p].nex[c] = cur; p = st[p].link; } if (p == -1) { st[cur].link = 0; } else { int q = st[p].nex[c]; if (st[p].len + 1 == st[q].len) { st[cur].link = q; } else { int clone = siz++; st[clone].len = st[p].len + 1; st[clone].nex = st[q].nex; st[clone].link = st[q].link; while (p != -1 && st[p].nex[c] == q) { st[p].nex[c] = clone; p = st[p].link; } st[q].link = st[cur].link = clone; } } last = cur; } inline void init() { st[0].len = 0; st[0].link = -1; siz++, last = 0; } inline void New() { cin >> str; init(); for (int i = 0; i < str.size(); i++) sam_extend(str[i]); } inline int find(string T) { int v = 0, l = 0, best = 0, bestpos = 0; for (int i = 0; i < T.size(); i++) { while (v && !st[v].nex.count(T[i])) { v = st[v].link; l = st[v].len; } if (st[v].nex.count(T[i])) { v = st[v].nex[T[i]]; l++; } if (l > best) { best = l; bestpos = i; } } return best; } }; map<int, String> S; int n; int main() { int q; scanf("%d%d", &n, &q); for (int i = 0; i < n; i++) S[i].New(); while (q--) { int a, b; scanf("%d%d", &a, &b); if (S[a].str.size() > S[b].str.size()) swap(a, b); if (vis[mp(a, b)]) printf("%d\n", vis[mp(a, b)]); else printf("%d\n", vis[mp(a, b)] = S[b].find(S[a].str)); } return 0; }
T3:
不会
浙公网安备 33010602011771号