暴力即可,注意需要判断字符串长度是否为5
map存 数字 -> 出现次数
滑动窗口,限制窗口内元素总和不大于k,等于k则为一个答案
注意有元素出窗口时不能只-1,需要减去该元素出现次数。
#include <cstdio> #include <cstring> #include <algorithm> #include <map> using namespace std; const int N = 10010; map<int, int> s; int n, k; int q[N], hh = 0, tt = 0; int main() { int T; scanf("%d", &T); while (T--) { s.clear(); hh = tt = 0; int sum = 0; bool success = false; scanf("%d%d", &n, &k); for (int i = 0; i < n; ++i) { int x; scanf("%d", &x); ++s[x]; } for (auto item : s) { int num = item.first, cnt = item.second; sum += cnt; q[tt++] = num; while (sum > k) { sum -= s[q[hh]]; ++hh; } if (sum == k) { success = true; printf("%d %d\n", q[hh], q[tt - 1]); break; } } if (!success) puts("-1"); } }
数字末尾零的个数 = min(数字2的因子个数,数字5的因子个数)
树链剖分,对子树的更新和查询转化为链上的连续节点操作。
转化为一个维护带懒更新的线段树。
最后三分钟调出来,发现query函数写错了,需要全部返回后在quert_tree里取min
LL a_cnt2, a_cnt5; // add_cntx 懒标记 LL s_cnt2, s_cnt5; // sum_cntx 以该节点为根的子树,所有2和5的因子的数量
#include <cstdio> #include <cstring> #include <algorithm> #include <map> using namespace std; typedef long long LL; const int N = 100010, M = (N << 1); int n, q; int w[N], h[N], e[M], ne[M], idx; int dfn[N], nw[N], cnt; int dep[N], sz[N], top[N], fa[N], son[N]; struct Tree { int l, r; LL a_cnt2, a_cnt5; LL s_cnt2, s_cnt5; }; Tree tr[N << 2]; void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; } void dfs1(int u, int father, int depth) { dep[u] = depth, fa[u] = father, sz[u] = 1; for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (j == father) continue; dfs1(j, u, depth + 1); sz[u] += sz[j]; if (sz[son[u]] < sz[j]) son[u] = j; } } void dfs2(int u, int t) { dfn[u] = ++cnt, nw[cnt] = w[u], top[u] = t; if (!son[u]) return; dfs2(son[u], t); for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (j == fa[u] || j == son[u]) continue; dfs2(j, j); } } pair<int, int> getval(int num) { int cnt2 = 0, cnt5 = 0; while (num) { if (num % 2 == 0) { ++cnt2; num /= 2; } else if (num % 5 == 0) { ++cnt5; num /= 5; } else { break; } } return {cnt2, cnt5}; } void pushup(int f) { tr[f].s_cnt2 = tr[f << 1].s_cnt2 + tr[f << 1 | 1].s_cnt2; tr[f].s_cnt5 = tr[f << 1].s_cnt5 + tr[f << 1 | 1].s_cnt5; } void pushdown(int f) { auto &root = tr[f], &left = tr[f << 1], &right = tr[f << 1 | 1]; if (root.a_cnt2 || root.a_cnt5) { left.a_cnt2 += root.a_cnt2, left.s_cnt2 += root.a_cnt2 * (left.r - left.l + 1); left.a_cnt5 += root.a_cnt5, left.s_cnt5 += root.a_cnt5 * (left.r - left.l + 1); right.a_cnt2 += root.a_cnt2, right.s_cnt2 += root.a_cnt2 * (right.r - right.l + 1); right.a_cnt5 += root.a_cnt5, right.s_cnt5 += root.a_cnt5 * (right.r - right.l + 1); root.a_cnt2 = root.a_cnt5 = 0; } } void build(int f, int l, int r) { auto [cnt2, cnt5] = getval(nw[r]); tr[f] = {l, r, 0, 0, cnt2, cnt5}; if (l == r) return; int mid = l + r >> 1; int lc = f << 1, rc = lc | 1; build(lc, l, mid), build(rc, mid + 1, r); pushup(f); } void update(int f, int l, int r, int k2, int k5) { if (l <= tr[f].l && r >= tr[f].r) { tr[f].a_cnt2 += k2; tr[f].a_cnt5 += k5; tr[f].s_cnt2 += k2 * (tr[f].r - tr[f].l + 1); tr[f].s_cnt5 += k5 * (tr[f].r - tr[f].l + 1); return; } pushdown(f); int mid = tr[f].l + tr[f].r >> 1; if (mid >= l) update(f << 1, l, r, k2, k5); if (mid < r) update(f << 1 | 1, l, r, k2, k5); pushup(f); } pair<LL, LL> query(int f, int l, int r) { if (l <= tr[f].l && r >= tr[f].r) return {tr[f].s_cnt2, tr[f].s_cnt5}; pushdown(f); int mid = tr[f].l + tr[f].r >> 1; LL res2 = 0, res5 = 0; if (mid >= l) { auto [cnt2, cnt5] = query(f << 1, l, r); res2 += cnt2; res5 += cnt5; } if (mid < r) { auto [cnt2, cnt5] = query(f << 1 | 1, l, r); res2 += cnt2; res5 += cnt5; } return {res2, res5}; } void update_tree(int u, int num) { auto [cnt2, cnt5] = getval(num); update(1, dfn[u], dfn[u] + sz[u] - 1, cnt2, cnt5); } LL quert_tree(int u) { auto [cnt2, cnt5] = query(1, dfn[u], dfn[u] + sz[u] - 1); return min(cnt2, cnt5); } int main() { memset(h, -1, sizeof h); scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%d", w + i); for (int i = 1; i < n; ++i) { int a, b; scanf("%d%d", &a, &b); add(a, b); add(b, a); } dfs1(1, -1, 1); dfs2(1, 1); build(1, 1, n); scanf("%d", &q); for (int i = 0; i < q; ++i) { int x, y; scanf("%d%d", &x, &y); update_tree(x, y); } for (int i = 1; i <= n; ++i) { LL res; res = quert_tree(i); printf("%lld", res); if (i != n) printf(" "); } return 0; } /* 5 1 2 6 3 1 1 2 1 3 2 4 2 5 1 2 5 */#百度##百度笔试#