因为不是一队……毫无晋级的压力……反正有压力也进不去呵呵呵……
开场zr看1006我看1010。。
1010我一直在wa。。。
zr的1006倒是比较轻松的过了。。。然后我让他帮我看10。。。。
跟他讲了半天我代码的逻辑。。。然后我自己看出来的。。。。比赛的代码。。。。写的十分混乱。。。。
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> typedef long long ll; using namespace std; const int N = 100005; vector<int> G[N]; int a[N], b[N]; int low[N]; int par[N]; int c[N]; int cntv; ll ans; int n; int lowbit(int x) { return x & (-x); } int sum(int n) //前n个数的和 { int ans = 0; while (n > 0) { ans += c[n]; n -= lowbit(n); } return ans; } void add(int pos, int num, int n) //在pos处加num { while (pos <= n) { c[pos] += num; pos += lowbit(pos); } } void dfs(int u) { //printf("==%d %d %d\n", u, a[u], low[ a[u] ]); //printf("n = %d\n", n); int lowu = low[ a[u] ]; int tmp = sum(lowu); for (unsigned i = 0; i < G[u].size(); ++i) { int v = G[u][i]; dfs(v); } int tmp2 = sum(lowu); add(a[u], 1, n); cntv++; //printf(">>%d %d %d\n", u, tmp, tmp2); ans += tmp2 - tmp; } void init() { memset(c, 0, sizeof c); memset(low, 0, sizeof low); memset(par, 0, sizeof par); } int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d", &T); while (T--) { ll k; init(); scanf("%d%lld", &n, &k); //printf("%d %lld\n", n, k); for (int i = 1; i <= n; ++i) { G[i].clear(); scanf("%d", &a[i]); b[i] = a[i]; } sort(b+1, b+1+n); int cnt = unique(b+1, b+1+n) - (b+1); //printf("cnt=%d\n",cnt); //for (int i = 1; i <= cnt; ++i) printf("|%d ", b[i]); printf("\n"); int idx = cnt; for (int i = 1; i <= cnt; ++i) { while ((ll)b[i]*b[idx--] > k) ; idx++; low[i] = idx; }//low[i]记录的是i*low[i]<=k的最大值 //for (int i = 1; i <= n; ++i) printf("%d ", low[i]); printf("\n"); for (int i = 1; i <= n; ++i) { a[i] = lower_bound(b+1, b+1+cnt, a[i]) - b; } //for (int i = 1; i <= n; ++i) { printf("%d %d\n", a[i], low[ a[i] ]); } int u, v; for (int i = 1; i < n; ++i) {//printf("i=%d\n", i); scanf("%d%d", &u, &v); G[u].push_back(v); par[v] = u; } int root = 1; while (par[root]) root = par[root]; //printf("root=%d\n", root); cntv = 0; ans = 0; dfs(root); printf("%lld\n", ans); } return 0; }