2018/8/21 qbxt测试
2018/8/21 qbxt测试
期望得分:0? 实际得分:0
思路:manacher 会写模板但是不会用 qwq
听了某人的鬼话,直接输出0,然后就gg了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = (int)2e6 + 10; typedef long long ll; char S[N]; int R[N], lf[N], rt[N]; int n; void init() { scanf("%s", S + 1), n = strlen(S + 1) << 1 | 1; for (int i = n; i >= 1; --i) S[i] = i & 1 ? '#' : S[i >> 1]; } void manacher() { int k = 1, p = 1; R[1] = 1, lf[1] = 0; for (int i = 2; i <= n; ++i) { int j = 2 * k - i; R[i] = min(R[j], p - i + 1); for ( ; i + R[i] <= n && i - R[i] >= 1 && S[i + R[i]] == S[i - R[i]]; ++R[i]); if (i + R[i] - 1 > p) { for (int j = p + 1; j <= i + R[i] - 1; ++j) lf[j] = j - i; k = i, p = i + R[i] - 1; } } k = n, p = n; rt[n] = 0; for (int i = n - 1; i >= 1; --i) { if (i - R[i] + 1 < p) { for (int j = p - 1; j >= i - R[i] + 1; --j) rt[j] = i - j; k = i, p = i - R[i] + 1; } } for (int i = 3; i <= n; i += 2) lf[i] = max(lf[i], lf[i - 2]); for (int i = n - 2; i >= 1; i -= 2) rt[i] = max(rt[i], rt[i + 2]); int ans = 0; for (int i = 1; i <= n; i += 2) if (lf[i] + rt[i] > ans) ans = lf[i] + rt[i]; printf("%d\n", ans); } int main() { freopen("string.in", "r", stdin); freopen("string.out", "w", stdout); init(); manacher(); return 0; }
期望得分:20?40? 实际得分:20
考场思路:树上两点间的最短路应该要求LCA,那就用树剖求吧 只会用树剖 qwq
欸?让着求路径乘积是什么鬼??线段树?? 那就树剖+线段树吧
这个区间怎么合并??不会 这题不会要用倍增LCA吧 不会啊 咕咕咕~
那就换暴力吧 枚举,然后乘起来
嗯。。答案好像不大对啊,这个样例是不是错了啊
20min 后。。。kao,我题目读错了
最后改了改,20分 qwq
正解:
#include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio> using namespace std; typedef long long LL; const int M = 100005; const int Mod = 1e9 + 7; LL S, T, G; int tot, n, m, k, t; int a[M], sum[M]; int to[M*2], net[M*2], head[M]; int deep[M], top[M], dad[M], size[M]; inline int read() { int x = 0, f = 1; char ch = getchar(); while(ch<'0' || ch>'9') { if(ch == '-') f = -1; ch = getchar(); } while(ch>='0' && ch<='9') x = x * 10 + ch - 48, ch = getchar(); return x * f; } inline void add(int u, int v) { to[++tot] = v; net[tot] = head[u]; head[u] = tot; to[++tot] = u; net[tot] = head[v]; head[v] = tot; } inline void dfs(int now) { size[now] = 1; deep[now] = deep[dad[now]] + 1; for(int i = head[now]; i; i = net[i]) if(dad[now] != to[i]) { dad[to[i]] = now; dfs(to[i]); size[now] += size[to[i]]; } } inline void dfsl(int now) { int t = 0; if(!top[now]) top[now] = now; for(int i = head[now]; i; i = net[i]) if(dad[now] != to[i] && size[to[i]] > size[t]) t = to[i]; if(t) { top[t] = top[now]; dfsl(t); } for(int i = head[now]; i; i = net[i]) if(dad[now] != to[i] && to[i] != t) dfsl(to[i]); } inline int lca(int x, int y) { while(top[x] != top[y]) { if(deep[top[x]] < deep[top[y]]) swap(x, y); x = dad[top[x]]; } return deep[x] > deep[y] ? y : x; } inline LL mul(int a, int b) { LL res = 0; while(b) { if(b & 1) res = (res + a) % Mod; a = (a + a) % Mod; b >>= 1; } return res; } inline LL bl(int tmp) { LL ans = 0; for(int i = 1; i <= tmp; i++) for(int j = i+1; j <= tmp; j++) ans = (mul(sum[i], sum[j]) + ans) % Mod; return ans; } inline void get(int l, int r) { if(l == r) return ; while(l != r) { sum[++t] = a[l]; l = dad[l]; } } int main() { freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); n = read(), m = read(), k = read(); for(int i = 1; i <= n; i++) a[i] = read(); for(int i = 1; i < n; i++) { int u, v; u = read(), v = read(); add(u, v); } dfs(1); dfsl(1); for(int i = 1; i <= m; i++) { memset(sum, 0, sizeof sum); int u, v; t = 0; u = read(); v = read(); if(k == 1) u ^= S, v ^= S; T = lca(u, v); get(u, T), get(v, T); sum[++t] = a[T]; G = bl(t); printf("%lld\n", G); if(k == 1) S = G; } fclose(stdin); fclose(stdout); return 0; }
#include <bits/stdc++.h> using namespace std; const int N = (int)2e5, mod = (int)1e9 + 7, inv = (mod + 1) >> 1; typedef int arr[N + 10]; typedef long long ll; int n, Q, K, ans, tot, j, k; arr pt, nt, g, d, ls[20], sqs[20], f[20]; arr a; struct queue { arr v; int f, r; }q; void link(int x, int y) { pt[++tot] = y, nt[tot] = g[x], g[x] = tot; pt[++tot] = x, nt[tot] = g[y], g[y] = tot; } void bfs() { q.v[q.f = q.r = 1] = 1, d[1] = 1; for ( ; q.f <= q.r; ) { int x = q.v[q.f++]; for (int c = 1; c <= 19; ++c) if (d[x] > (1 << c)) { f[c][x] = f[c - 1][f[c - 1][x]]; ls[c][x] = (ls[c - 1][x] + ls[c - 1][f[c - 1][x]]) % mod; sqs[c][x] = (sqs[c - 1][x] + sqs[c - 1][f[c - 1][x]]) % mod; } else break; for (int i = g[x]; i; i = nt[i]) if (!d[pt[i]]) { d[pt[i]] = d[x] + 1; f[0][pt[i]] = x, ls[0][pt[i]] = a[pt[i]], sqs[0][pt[i]] = (ll)a[pt[i]] * (ll)a[pt[i]] % mod; q.v[++q.r] = pt[i]; } } } int query(int x, int y) { if (d[x] > d[y]) swap(x, y); int sq = 0, l = 0; for (int c = 19; c >= 0; --c) if (d[y] - (1 << c) >= d[x]) (l += ls[c][y]) %= mod, (sq += sqs[c][y]) %= mod, y = f[c][y]; if (x == y) { l = (l + a[y]) % mod, (sq += (ll)a[y] * (ll)a[y] % mod) %= mod; l = (ll)l * (ll)l % mod; return (ll)(l + mod - sq) * (ll)inv % mod; } for (int c = 19; c >= 0; --c) if (f[c][x] != f[c][y]) { (l += (ls[c][x] + ls[c][y]) % mod) %= mod, (sq += (sqs[c][x] + sqs[c][y]) % mod) %= mod; x = f[c][x], y = f[c][y]; } (l += (ls[0][x] + ls[0][y]) % mod) %= mod, (sq += (sqs[0][x] + sqs[0][y]) % mod) %= mod; y = f[0][y]; (l += a[y]) %= mod, (sq += (ll)a[y] * (ll)a[y] % mod) %= mod; l = (ll)l * (ll)l % mod; return (ll)(l + mod - sq) * (ll)inv % mod; } int main() { freopen("tree.in", "r", stdin); freopen("tree.out", "w", stdout); scanf("%d %d %d", &n, &Q, &K); for (int i = 1; i <= n; ++i) scanf("%d", a + i); for (int i = 1; i < n; ++i) { scanf("%d %d", &j, &k); link(j, k); } bfs(); ans = 0; for ( ; Q--; ) { scanf("%d %d", &j, &k); if (K) j ^= ans, k ^= ans; printf("%d\n", ans = query(j, k)); } return 0; }
期望得分:0 实际得分:0
思路:没有思路 期望是什么??不知道
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N = 1000; typedef int arr[N + 10][N + 10]; int n, m, k, t, u, v; arr s, c; int Sum(int l1, int r1, int l2, int r2) { return s[l2][r2] - s[l1 - 1][r2] - s[l2][r1 - 1] + s[l1 - 1][r1 - 1]; } long double Pow(long double x, int y) { long double t = x, r = 1; for ( ; y; y >>= 1, t = t * t) if (y & 1) r = r * t; return r; } int main() { freopen("swap.in", "r", stdin); freopen("swap.out", "w", stdout); scanf("%d%d%d%d\n", &n, &m, &k, &t); for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) s[i][j] = c[i][j] = 1; ll tot = n * m; for (int i = 1; i <= t; ++i) { scanf("%d%d\n", &u, &v); s[u][v] = c[u][v] = 0, --tot; } for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1]; if (!tot) return printf("%.12lf\n", 0.), 0; long double exp = tot; tot *= tot; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (c[i][j]) { ll cx = Sum(1, 1, i, j), cy = Sum(i, j, n, m), ans = cx * cy; cx = Sum(1, j, i, m), cy = Sum(i, 1, n, j); ans += cx * cy; cx = Sum(1, j, i, j), cy = Sum(i, j, n, j); ans -= cx * cy; cx = Sum(i, 1, i, j), cy = Sum(i, j, i, m); ans -= cx * cy; ans = ans * 2LL + 1LL; long double e = (long double)1 - (long double)2 * (long double)ans / (long double)tot; exp += Pow(e, k); } } } exp /= (long double)2; printf("%.12Lf\n", exp); return 0; }