【Codeforces150E】Freezing with Style
来源:互联网 发布:网络信用卡有哪些 编辑:程序博客网 时间:2024/06/05 18:56
题意:求树上路径长度在
显然需要二分
这个可以树分治。每条路径都并定在某层的重心。所以考虑怎么求出
第一想法是按某种顺序枚举子树,然后通过线段树维护深度确定的到
所以就有一种神奇方法:
按从小到大(深度或者子树大小)枚举子树,然后每将一颗子树更新进到数组前,用双指针队列扫描。
类似于启发式合并的方法,会发现这样是每步均摊
(是不是感觉是一道斯波题??然而我写的时间跟代码长度都破天际了啊。。。)
附图:
#include <bits/stdc++.h>#define gc getchar()#define ll long long#define mid (l+r>>1)#define N 100009#define inf 0x3f3f3f3fusing namespace std;int n, LL, RR, first[N], number = 1, sz[N], fa[N], Max[N];int len, now_x, now_y, Ans_x, Ans_y, SZ[N], Ans = -1, deep[N];vector<int> go[N];struct edge{ int to, next, val, vis; void add(int x, int y, int z) { to = y, next = first[x], first[x] = number, val = z; } int v(int lim) { return val >= lim ? 1 : -1; }}e[N << 1];struct node{ int val, pos; node(int val = 0, int pos = 0) :val(val), pos(pos) {} bool operator <(const node &rhs) const { return val < rhs.val; } bool operator <=(const node &rhs) const { return val <= rhs.val; }}Max_val[N << 2];bool cmp(int x, int y){ return SZ[e[x].to] < SZ[e[y].to];}node max(const node &A, const node &B){ return A < B ? B : A;}int read(){ int x = 1; char ch; while (ch = gc, ch<'0' || ch>'9') if (ch == '-') x = -1; int s = ch - '0'; while (ch = gc, ch >= '0'&&ch <= '9') s = s * 10 + ch - '0'; return x*s;}void Get_G(int x, int y, int &G){ sz[x] = 1, Max[x] = 0; for (int i = first[x]; i; i = e[i].next) if (!e[i].vis&&e[i].to != fa[x]) { Get_G(e[i].to, y, G); sz[x] += sz[e[i].to]; Max[x] = max(Max[x], sz[e[i].to]); } Max[x] = max(Max[x], y - sz[x]); if (Max[x] < Max[G]) G = x;}node Q[N << 1], q[N << 1];int pos[N << 1];void Dfs(int G, int y, int x, int last, int sum, int depth, int lim){ q[depth] = max(q[depth], node(sum, x)); if (depth >= LL&&depth <= RR&&sum >= 0) { now_x = x, now_y = G; return; } for (int i = first[x]; i; i = e[i].next) if (e[i].to != last && !e[i].vis) { Dfs(G, y, e[i].to, x, sum + e[i].v(lim), depth + 1, lim); if (now_x&&now_y) return; }}bool check(int G, int tmp, int y, int lim){ for (int i = 1; i <= y; i++) Q[i] = node(-inf, 0); now_x = now_y = 0; for (int i = 0; i < go[G].size(); i++) if (!e[go[G][i]].vis) { int sz_now = 0; if (go[G][i] == tmp) sz_now = y - sz[G]; else sz_now = sz[e[go[G][i]].to]; for (int j = 1; j <= sz_now; j++) q[j] = node(-inf, 0); Dfs(G, y, e[go[G][i]].to, G, e[go[G][i]].v(lim), 1, lim); if (now_x&&now_y) return true; int head = 1, tail = 0, r = max(1, LL - sz_now); pos[tail] = 0; for (int j = sz_now; j; j--) { while (r + j <= RR&&node(-inf, 0) < Q[r]&&r <= y) { while (head <= tail&&Q[pos[tail]] <= Q[r]) tail--; pos[++tail] = r++; } while (head <= tail&&pos[head] + j < LL) head++; if (head <= tail&&Q[pos[head]].val + q[j].val >= 0&&pos[head] + j >= LL&&pos[head] + j <=RR) { now_x = Q[pos[head]].pos; now_y = q[j].pos; return true; } } for (int j = 1; j <= sz_now; j++) Q[j] = max(Q[j], q[j]); } return false;}void solve(int x, int y){ int G = 0; Get_G(x, y, G); int tmp = 0; for (int i = first[G]; i; i = e[i].next) if (e[i].to == fa[G]) tmp = i; int l = 0, r = inf, ret = 0, ret_x = 0, ret_y = 0; while (l<=r) { if (check(G, tmp, y, mid)) ret_x = now_x, ret_y = now_y, ret = mid, l = mid + 1; else r = mid - 1; } if (ret > Ans) { Ans = ret; Ans_x = ret_x; Ans_y = ret_y; } if (tmp && !e[tmp].vis) { e[tmp].vis = e[tmp ^ 1].vis = 1; solve(x, y - sz[G]); } for (int i = first[G]; i; i = e[i].next) if (!e[i].vis) { e[i].vis = e[i ^ 1].vis = 1; solve(e[i].to, sz[e[i].to]); }}void dfs(int x){ SZ[x] = 1; deep[x] = deep[fa[x]] + 1; for (int i = first[x]; i; i = e[i].next) { if (e[i].to != fa[x]) fa[e[i].to] = x, dfs(e[i].to), SZ[x] += SZ[e[i].to]; go[x].push_back(i); } int tmp = SZ[fa[x]]; SZ[fa[x]] = n - SZ[x]; sort(go[x].begin(), go[x].end(), cmp); SZ[fa[x]] = tmp;}int main(){ Max[0] = inf; n = read(), LL = read(), RR = read(); for (int i = 1; i < n; i++) { int x = read(), y = read(), z = read(); e[++number].add(x, y, z), e[++number].add(y, x, z); } dfs(1); solve(1, n); printf("%d %d\n", Ans_x, Ans_y); return 0;}
阅读全文
0 0
- [Codeforces150E]Freezing with Style
- 【Codeforces150E】Freezing with Style
- Codeforces 150E Freezing with Style (树分治)
- Printing with Style
- modeling with human-style
- Freezing AjaxMapControl
- Style page elements with CSS
- LinuxKernel:Freezing filesystems
- Freezing of tasks
- Sharing a Single Style with Heterogeneous Elements
- 【资料】Exporting GridView to Excel With Style
- CSU 1097 Gifts with different style
- at 'theme' with value '@style/ AppTheme'
- Art Generation with Neural Style Transfer
- Art Generation with Neural Style Transfer
- Freezing of tasks [Kernel Documents]
- Freezing of tasks [Kernel Documents]
- Freezing of tasks [Kernel Documents]
- ASM常用命令
- 【BZOJ 1093】【ZJOI 2007】【最大半连通子图】【tarjan强连通分量】【拓扑排序dp】
- Java BufferedReader readLine方法i
- windows中修改tomcat运行窗口的名字
- 如何持久化会话级别的Session
- 【Codeforces150E】Freezing with Style
- 先排序,再分组,再排序,再将组内元素合并
- 关于面向对象和面向过程
- 去掉IntelliJ IDEA 中 mybatis 对应的 xml 文件警告
- 史上最全开发者工具详解,在开发者工具里如何判断一个请求是ajax请求
- 运行时数据区
- IntelliJ IDEA报class is never used
- 玩转windbg软件调试视频教程发布-windbg入门教程
- [bzoj4597][Shoi2016]随机序列 线段树