【主席树】 HDOJ 4729 An Easy Problem for Elfness

来源:互联网 发布:淘宝达人也能赚佣金吗 编辑:程序博客网 时间:2024/06/07 14:20

在树上建立主席树。。。然后如果a>=b,那么就只建边,初始值主席树上查最小值。否则在建一条边或者不建边。不建边的情况下,在主席树上找最小的限制解。。

#include <iostream>#include <queue>#include <stack>#include <map>#include <set>#include <bitset>#include <cstdio>#include <algorithm>#include <cstring>#include <climits>#include <cstdlib>#include <cmath>#include <time.h>#define maxn 100005 #define maxm 200005#define eps 1e-7#define mod 1000000007#define INF 0x3f3f3f3f#define PI (acos(-1.0))#define lowbit(x) (x&(-x))#define mp make_pair#define ls o<<1#define rs o<<1 | 1//#define lson o<<1, L, mid //#define rson o<<1 | 1, mid+1, R#define pii pair<int, int>#pragma comment(linker, "/STACK:16777216")//typedef long long LL;//typedef unsigned long long ULL;//typedef int LL; using namespace std;//LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}//LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}// head#define lson o->ch[0], L, mid#define rson o->ch[1], mid+1, Rconst int LL = 0;const int RR = 10000;struct Edge{int v, w;Edge *next;}*H[maxn], *edges, E[maxm];struct node{int cnt, sum;node *ch[2];}*h[maxn], *tail, pool[maxm << 4];const int M = 20;int anc[maxn][M];int dep[maxn];int n, m;void addedges(int u, int v, int w){edges->v = v;edges->w = w;edges->next = H[u];H[u] = edges++;}node* newnode(){tail->cnt = tail->sum = 0;tail->ch[0] = tail->ch[1] = NULL;return tail++;}int to(int u, int d){for(int i = M - 1; i >= 0; i--) if(dep[anc[u][i]] >= d) u = anc[u][i];return u;}int lca(int u, int v){if(dep[u] < dep[v]) swap(u, v);u = to(u, dep[v]);for(int i = M - 1; i >= 0; i--) if(anc[u][i] != anc[v][i]) u = anc[u][i], v = anc[v][i];return u == v ? u : anc[u][0];}void init(){tail = pool;edges = E;memset(H, 0, sizeof H);}node* build(int L, int R){if(L == R) return newnode();int mid = (L + R) >> 1;node *o = newnode();o->ch[0] = build(L, mid);o->ch[1] = build(mid+1, R);return o;}void pushup(node *o){o->cnt = o->ch[0]->cnt + o->ch[1]->cnt;o->sum = o->ch[0]->sum + o->ch[1]->sum;}node* update(node* o, int L, int R, int v){node *p = newnode();*p = *o;if(L == R) {p->cnt++, p->sum += v;return p;}int mid = (L + R) >> 1;if(v <= mid) p->ch[0] = update(lson, v);else p->ch[1] = update(rson, v);pushup(p);return p;}void dfs(int u, int fa){anc[u][0] = fa;for(Edge *e = H[u]; e; e = e->next) if(e->v != fa) {int v = e->v, w = e->w;h[v] = update(h[u], LL, RR, w);dep[v] = dep[u] + 1;dfs(v, u);}}int query_min(node *a, node *b, node *c, int L, int R){if(L == R) return L;int lcnt = a->ch[0]->cnt + b->ch[0]->cnt - 2 * c->ch[0]->cnt;int mid = (L + R) >> 1;if(lcnt) return query_min(a->ch[0], b->ch[0], c->ch[0], L, mid);else return query_min(a->ch[1], b->ch[1], c->ch[1], mid+1, R);}int query(node *a, node *b, node *c, int L, int R, int cnt, int kk){if(L == R) {int t = a->cnt + b->cnt - 2 * c->cnt;if(cnt > kk) return L-1;else return L + (kk - cnt) / (cnt + t);}int lcnt = a->ch[0]->cnt + b->ch[0]->cnt - 2 * c->ch[0]->cnt;int lsum = a->ch[0]->sum + b->ch[0]->sum - 2 * c->ch[0]->sum;int mid = (L + R) >> 1;int t = cnt * (mid - L + 1) + lcnt * mid - lsum;if(t <= kk) query(a->ch[1], b->ch[1], c->ch[1], mid+1, R, cnt + lcnt, kk - t);else return query(a->ch[0], b->ch[0], c->ch[0], L, mid, cnt, kk);}void work(){int u, v, w, kk, a, b;scanf("%d%d", &n, &m);for(int i = 1; i < n; i++) {scanf("%d%d%d", &u, &v, &w);addedges(u, v, w);addedges(v, u, w);}h[1] = build(LL, RR);dfs(1, 1);for(int i = 1; i < M; i++)for(int j = 1; j <= n; j++)anc[j][i] = anc[anc[j][i-1]][i-1];while(m--) {scanf("%d%d%d%d%d", &u, &v, &kk, &a, &b);int c = lca(u, v);int ans = query_min(h[u], h[v], h[c], LL, RR);if(a <= b) {ans += kk / a;printf("%d\n", ans);}else {int t1 = ans;if(kk > a) t1 += 1 + (kk - a) / b;int t2 = query(h[u], h[v], h[c], LL, RR, 0, kk / b);if(t1 > t2) printf("%d\n", t1);else printf("%d\n", t2);}}}int main(){int _;scanf("%d", &_);for(int i = 1; i <= _; i++) {printf("Case #%d:\n", i);init();work();}return 0;}


0 0