首页 > 代码库 > HDU5877 线段树
HDU5877 线段树
题目大意:给你一棵树,有n-1条边,每条边都有方向,每个顶点有权值,给出weak pair的定义是val[u]*val[v] <=k,u是v的祖先,问有多少对这样的顶点
思路:创建线段树,通过dfs动态创建,每次都不断更新。因为我们只能是根节点开始往下的,所以我们遍历到兄弟节点的之前要把其他的兄弟节点的信息给删除掉。(这就和用vis标记一样的,一会儿变为true,一会儿变为false)
不过我很奇怪,为啥我的代码没有吧k/a[i]放进去就迷之RE了
当然,这道题也可以用主席树做,也可以用treap做
//看看会不会爆int!数组会不会少了一维!//取物问题一定要小心先手胜利的条件#include <bits/stdc++.h>using namespace std;#define LL long long#define ALL(a) a.begin(), a.end()#define pb push_back#define mk make_pair#define fi first#define se secondconst int maxn = 4e5 + 5;LL a[maxn], b[maxn], d[maxn], tree[maxn * 4];LL n, m, k, lenb, ans;vector<int> E[maxn];int query(int o, int l, int r, int ql, int qr){ if (l >= ql && r <= qr){ return tree[o]; } int cnt = 0; int mid = (l + r) / 2; if (ql <= mid) cnt += query(o << 1, l, mid, ql, qr); if (qr > mid) cnt += query(o << 1 | 1, mid + 1, r, ql, qr); return cnt;}inline void push_up(int o){ int lb = o << 1, rb = o << 1 | 1; tree[o] = tree[lb] + tree[rb];}void update (int o, int l, int r, int pos, int val){ if (l == r && l == pos) { tree[o] += val; return ; } int mid = (l + r) / 2; if (pos <= mid) update(o << 1, l, mid, pos, val); if (pos > mid) update(o << 1 | 1, mid + 1, r, pos, val); push_up(o);}void dfs(int u){ int pos = lower_bound(b + 1, b + 1 + m, a[u]) - b; int posk = lower_bound(b + 1, b + 1 + m, k / a[u]) - b; ans += query(1, 1, lenb, 1, posk); int len = E[u].size(); update(1, 1, lenb, pos, 1); for (int i = 0; i < len; i++){ int v = E[u][i]; dfs(v); } update(1, 1, lenb, pos, -1);}int main(){ int t; cin >> t; while (t--){ memset(d, 0, sizeof(d)); memset(tree, 0, sizeof(tree)); scanf("%I64d%I64d", &n, &k); for (int i = 1; i <= n; i++){ scanf("%I64d", a + i); b[i] = a[i]; E[i].clear(); } m = n; for (int i = 1; i <= n; i++) b[++m] = k / a[i]; sort(b + 1, b + 1 + m); lenb = unique(b + 1, b + 1 + m) - b - 1;///序列长度1~n ///printf("lenb = %d\n", lenb); for (int i = 1; i <= n - 1; i++){ int u, v; scanf("%d%d", &u, &v); E[u].pb(v); d[v]++; } ans = 0; for (int i = 1; i <= n; i++){ if (d[i] == 0){ dfs(i); break; } } printf("%I64d\n", ans); } return 0;}
HDU5877 线段树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。