原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3083

说话间又一个多月过去了。。该来除除草了,每天都是训练、没效率,训练、没效率。。省选考得不好不说了=-继续努力吧

题目大意:维护一棵有根树,支持三个操作:换根; 一条链上都改为一个值; 求某个子树的Min

算法分析:
裸的动态树问题,非常简单啦。只涉及链上和子树操作,树的形态没有改变,所以用剖分来搞。就按照最开始给定的那个根剖分,得到一个剖分序。在换根之后查子树的时候注意一件事情,就是在最早的定根的形态中,现在的根如果在要查询的那个子树的根的某个儿子的子树上的话,就需要查询整个树除去这个儿子的子树的最小值,否则就是原来的那个子树的最小值。至于怎么判断,我用剖分序乱搞的=-

参考代码:

 //date 20140521
#include <cstdio>
#include <cstring> const int maxn = ;
const int INF = 0x7FFFFFFF; template <typename T> inline void swap(T &a, T &b){T x = a; a = b; b = x;}
inline int innew(int &a, int b){if(a < b){a = b; return ;} return ;}
inline int denew(int &a, int b){if(a > b){a = b; return ;} return ;}
inline int min(int a, int b){return a < b ? a : b;} inline int getint()
{
int ans(); char w = getchar();
while(w < '' || '' < w) w = getchar();
while('' <= w && w <= '')
{
ans = ans * + w - '';
w = getchar();
}
return ans;
} int n, m, root;
struct edge
{
int v, next;
}E[maxn << ];
int nedge, a[maxn], num[maxn]; inline void add(int u, int v)
{
E[++nedge].v = v;
E[nedge].next = a[u];
a[u] = nedge;
} int dpt[maxn], p[maxn], size[maxn], hp[maxn], hs[maxn];
int order[maxn], ps[maxn], ped[maxn]; inline void dfs_one(int v0)
{
static int d[maxn], now[maxn];
int last, i, j;
memcpy(now, a, sizeof a);
d[last = dpt[v0] = size[v0] = ] = v0;
while(last)
{
if(!(j = now[i = d[last]]))
{
if((--last) && (size[d[last]] += size[i], size[hs[d[last]]] < size[i]))
hs[d[last]] = i;
continue;
}
if(p[i] != E[j].v) dpt[d[++last] = E[j].v] = dpt[p[E[j].v] = i] + (size[E[j].v] = );
now[i] = E[j].next;
}
} inline void dfs_two(int v0)
{
static int d[maxn], now[maxn];
int last, i, j, tot;
d[last = ] = order[ps[v0] = ped[v0] = tot = ] = v0;
memset(now, 0xFF, sizeof now);
for(int i = ; i <= n; ++i) hp[i] = i;
while(last)
{
if(!(j = now[i = d[last]]))
{
if(--last) innew(ped[d[last]], ped[i]);
continue;
}
if(j == -)
{
if(hs[i]) hp[d[++last] = order[ps[hs[i]] = ped[hs[i]] = ++tot] = hs[i]] = hp[i];
now[i] = a[i]; continue;
}
if(E[j].v != hs[i] && E[j].v != p[i]) d[++last] = order[ps[E[j].v] = ped[E[j].v] = ++tot] = E[j].v;
now[i] = E[j].next;
}
} struct Segment_Tree
{
struct node
{
node *s[];
int l, r, Min, cov;
node(){}
int cover(int v){Min = v; cov = ;}
void pushdown()
{
if(cov && l < r){s[]->cover(Min); s[]->cover(Min);}
cov = ;
}
void update(){ Min = min(s[]->Min, s[]->Min);}
}*root, pond[maxn << ];
int stop; void change(node *p, int l, int r, int v)
{
if(l <= p->l && p->r <= r){p->cover(v); return;}
p->pushdown();
int mid = (p->l + p->r) >> ;
if(l <= mid) change(p->s[], l, r, v);
if(r > mid) change(p->s[], l, r, v);
p->update();
} int query(node *p, int l, int r)
{
if(l <= p->l && p->r <= r){return p->Min;}
p->pushdown();
int mid = (p->l + p->r) >> ;
int ans = INF;
if(l <= mid) denew(ans, query(p->s[], l, r));
if(r > mid) denew(ans, query(p->s[], l, r));
return ans;
} node *build(int l, int r)
{
node *p = &pond[stop++];
p->s[] = p->s[] = NULL; p->cov = ; p->l = l; p->r = r;
if(l == r) {p->Min = num[order[l]]; return p;}
int mid = (l + r) >> ;
p->s[] = build(l, mid);
p->s[] = build(mid + , r);
p->update();
return p;
} void preset(){stop = ; root = build(, n);} int get_min(int l, int r)
{
if(l > r) swap(l, r);
return query(root, l, r);
} void change(int l, int r, int v)
{
if(l > r) swap(l, r);
change(root, l, r, v);
}
}MEOW; inline void reroot(int r){root = r;}
inline void change(int x, int y, int v)
{
int x0 = x, y0 = y;
while(hp[x0] != hp[y0])
{
if(dpt[hp[x0]] > dpt[hp[y0]])
{
MEOW.change(ps[hp[x0]], ps[x0], v);
x0 = p[hp[x0]];
}else{
MEOW.change(ps[hp[y0]], ps[y0], v);
y0 = p[hp[y0]];
}
}
MEOW.change(ps[x0], ps[y0], v);
}
inline int query(int x)
{
if(x == root) return MEOW.root->Min;
int x0 = x, r = root, sgn = , tp = ;
if(hp[x0] == hp[r] && dpt[r] > dpt[x]) sgn = ;
while(hp[x0] != hp[r])
{
if(dpt[hp[x0]] > dpt[hp[r]]) {sgn = ; break;}
if(p[hp[r]] == x0) tp = hp[r];
sgn = ; r = p[hp[r]];
}
if(dpt[r] < dpt[x]) sgn = ;
if(sgn) return MEOW.get_min(ps[x], ped[x]);
if(r != x0) tp = hs[x0];
int ans = MEOW.get_min(, ps[tp] - );
if(ped[tp] != n) denew(ans, MEOW.get_min(ped[tp] + , n));
return ans;
} int main()
{
freopen("bzoj.in", "r", stdin);
freopen("bzoj.out", "w", stdout); n = getint(); m = getint();
for(int i = ; i < n; ++i)
{
int x = getint(), y = getint();
add(x, y); add(y, x);
}
for(int i = ; i <= n; ++i) num[i] = getint() - ;
root = getint();
dfs_one(root); dfs_two(root);
MEOW.preset();
for(int i = ; i <= m; ++i)
{
int k, x, y, v;
k = getint();
switch(k)
{
case : x = getint(); reroot(x); break;
case : x = getint(); y = getint(); v = getint() - ; change(x, y, v); break;
case : x = getint(); printf("%u\n", (unsigned)query(x) + 1u); break;
}
}
return ;
}

BZOJ 3083 - 遥远的国度的更多相关文章

  1. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  2. BZOJ 3083: 遥远的国度 dfs序,树链剖分,倍增

    今天再做一天树的题目,明天要开始专攻图论了.做图论十几天之后再把字符串搞搞,区域赛前再把计几看看. 3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 128 ...

  3. BZOJ 3083 遥远的国度 树链剖分

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 797  Solved: 181[Submit][Status] Descrip ...

  4. bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了…… O( nlog ...

  5. BZOJ 3083 遥远的国度(树链剖分+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3083 [题目大意] 链修改,子树最小值查询和换根操作 [题解] 树链剖分练习题. [代 ...

  6. BZOJ 3083 遥远的国度(树链剖分+LCA)

    Description 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要z ...

  7. bzoj 3083 遥远的国度 —— 树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 换根后路径还是不变,子树分类讨论一下,树剖后线段树维护即可. 代码如下: #inclu ...

  8. BZOJ 3083: 遥远的国度(树链剖分+DFS序)

    可以很显而易见的看出,修改就是树链剖分,而询问就是在dfs出的线段树里查询最小值,但由于这道题会修改根节点,所以在查询的时候需判断x是否为root的祖先,如果不是就直接做,是的话应该查询从1-st[y ...

  9. BZOJ 3083 遥远的国度 树链剖分+脑子

    唉..又调了半天QWQ..为何读入挂了.....莫非读入是反着的????据ywy学长所言如是...OvO震惊 这啥骚题啊...还要换根...不过清明讲过...(然鹅我现在才做... 先随便选个点(比如 ...

随机推荐

  1. 火狐和IE之间的7个JavaScript差异

    尽管 JavaScript 历史上使用冗长而令人生厌的代码块来标的特定浏览器的时期已经结束了,但是偶尔使用一些简单的代码块和对象检测来确保一些代码在用户机器上正常工作依然是必要的. 这篇文章中,我会略 ...

  2. linux yum 命令 详解

    linux yum命令详解 yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理,能 ...

  3. React Native 简介:用 JavaScript 搭建 iOS 应用(2)

    [编者按]本篇文章的作者是 Joyce Echessa--渥合数位服务创办人,毕业于台湾大学,近年来专注于协助客户进行 App 软体以及网站开发.本篇文章中,作者介绍通过 React Native 框 ...

  4. iOS第三方语音-讯飞语音

    官方网站:http://www.xfyun.cn/ 注册还要绑定微信,坑啊,识别率感觉没得微信语音好,但是微信语音审核一直不过,研究下这个 1.下载sdk,主要就下面几个文件,我主要用的是语音识别

  5. 获取及管理Android 手机运营商及状态

    主要类 TelephonyManager: telephonyManager.getCellLocation();//获得服务区 telephonyManager.getCellId();//获得服务 ...

  6. ==和equals的区别

    == :是判断两个变量或实例是不是指向同一个内存空间equals :是判断两个变量或实例所指向的内存空间的值是不是相同 结论:欲比较栈中数据是否相等,请用= =:欲比较堆中数据是否相等,请用equal ...

  7. UVA 10341 二分搜索

    Solve the equation:p ∗ e−x + q ∗ sin(x) + r ∗ cos(x) + s ∗ tan(x) + t ∗ x2 + u = 0where 0 ≤ x ≤ 1.In ...

  8. node入门开发遇到的问题

    最近在看node入门这本书,https://cnodejs.org/getstart 里面是跟随作者完成一个小的demo,书中不免会有遗漏的,下面是我在实现里面最后一个例子时遇到的问题,希望能够帮助其 ...

  9. JS中的this好神奇,都把我弄晕了

    一.this的常见判断: 1.函数预编译过程 this —> window 2.全局作用域里 this —> window 3.call/apply 可以改变函数运行时this指向 4.o ...

  10. http://www.cnblogs.com/flyoung2008/archive/2013/08/11/3251148.html

    http://www.cnblogs.com/flyoung2008/archive/2013/08/11/3251148.html