原题地址: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. Oracle 时间处理(加减)

    一. 类似SQL SERVER中DateAdd select sysdate,add_months(sysdate,12) from dual;        --加1年 select sysdate ...

  2. Environment.SpecialFolder.CommonApplicationData

    private void button1_Click(object sender, EventArgs e) { var path=Environment.GetFolderPath(Environm ...

  3. MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能

    MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能 Clicks: Date: -- :: Power By 李轩Lane TagMysql计数器高性能 现在有很多的项目,对计数器的实现 ...

  4. HDU2829 Lawrence(斜率优化dp)

    学了模板题之后上网搜下斜率优化dp的题目,然后就看到这道题,知道是斜率dp之后有思路就可以自己做不出来,要是不事先知道的话那就说不定了. 题意:给你n个数,一开始n个数相邻的数之间是被东西连着的,对于 ...

  5. C#中对象的输出

    假设有个Costmer类如下: class Costmer { public string Id { get; set; } public string City { get; set; } publ ...

  6. 传说中的WCF(3):多个协定

    我们知道,WCF服务端是先定义服务协定,其实就是一个接口,然后通过实现接口来定义服务类.那么,有一个问题,如果一个服务类同时实现N个接口(也就是有N个协定)呢?结果会如何? 不必猜,我们还是通过实验来 ...

  7. HDU 5596/BestCoder Round #66 (div.2) GTW likes math 签到

    GTW likes math  Memory Limit: 131072/131072 K (Java/Others) 问题描述 某一天,GTW听了数学特级教师金龙鱼的课之后,开始做数学<从自主 ...

  8. pku 1703(种类并查集)

    题目链接:http://poj.org/problem?id=1703 思路;个人觉得本质上还是和带权并查集一样的,只不过多了一个MOD操作,然后就是向量关系图稍微改动一下就变成种类并查集了,对于本题 ...

  9. MongoDB 管理工具:Robomongo

    http://www.open-open.com/lib/view/open1383029577546.html

  10. eclipse导入的工程前面有感叹号是什么意思

    1.尤其是从其他地方拷贝来并且直接加载的工程,刚打开往往会看到工程的图标上有个红色的感叹号,这是因为build path 出错了,里面有缺失或者无法找到的包. 2. 原因:显示红色感叹号是因为jar包 ...