BZOJ 3083 - 遥远的国度
原题地址: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 - 遥远的国度的更多相关文章
- BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 Solved: 795[Submit][Status][Discu ...
- BZOJ 3083: 遥远的国度 dfs序,树链剖分,倍增
今天再做一天树的题目,明天要开始专攻图论了.做图论十几天之后再把字符串搞搞,区域赛前再把计几看看. 3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 128 ...
- BZOJ 3083 遥远的国度 树链剖分
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 797 Solved: 181[Submit][Status] Descrip ...
- bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了…… O( nlog ...
- BZOJ 3083 遥远的国度(树链剖分+线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3083 [题目大意] 链修改,子树最小值查询和换根操作 [题解] 树链剖分练习题. [代 ...
- BZOJ 3083 遥远的国度(树链剖分+LCA)
Description 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要z ...
- bzoj 3083 遥远的国度 —— 树链剖分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 换根后路径还是不变,子树分类讨论一下,树剖后线段树维护即可. 代码如下: #inclu ...
- BZOJ 3083: 遥远的国度(树链剖分+DFS序)
可以很显而易见的看出,修改就是树链剖分,而询问就是在dfs出的线段树里查询最小值,但由于这道题会修改根节点,所以在查询的时候需判断x是否为root的祖先,如果不是就直接做,是的话应该查询从1-st[y ...
- BZOJ 3083 遥远的国度 树链剖分+脑子
唉..又调了半天QWQ..为何读入挂了.....莫非读入是反着的????据ywy学长所言如是...OvO震惊 这啥骚题啊...还要换根...不过清明讲过...(然鹅我现在才做... 先随便选个点(比如 ...
随机推荐
- MVC bundle(CSS或JS)
无论是有asp还是asp.net,还是php做网站经验的都知道当我们需要css或者js文件的时候我们需要在<head></head>标签中间导入我们需要的js或者css文件的路 ...
- JavaScript之Cookie讲解
什么是 Cookie “cookie 是存储于访问者的计算机中的变量.每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie.你可以使用 JavaScript 来创建和取回 cookie ...
- js函数延迟执行
function delay(value){ //全局变量保存当前值 window._myTempDalayValue = value; setTimeout(function(){ //延时之后与全 ...
- maven 构建spring ssh mybatis 配置
详情参与 http://blog.csdn.net/yuguiyang1990/article/details/8811817 前面我们使用Maven构建了Struts2项目,这里我们来试一下Hibe ...
- 《暗黑世界GM管理后台系统》部署+功能说明文档
http://www.9miao.com/product-10-1073.html <暗黑世界GM管理后台系统>部署+功能说明文档 <暗黑世界GM管理后台系统>部署+功能说明文 ...
- Scala学习——数组/映射/元组
[<快学Scala>笔记] 数组 / 映射 / 元组 一.数组 1.定长数组 声明数组的两种形式: 声明指定长度的数组 val 数组名= new Array[类型](数组长度) 提供数组初 ...
- 运行时修改TimerTask的执行周期
java.util.TimerTask类的执行周期period变量的声明如下: /** * Period in milliseconds for repeating tasks. A positive ...
- ZOJ2923 Calculate Roads(SPFA上的dp)
算是学了图dp后的第一次应用吧.题目其实真的是非常不严谨,什么都没说,基本靠猜,而且严格来说数据应该会有爆int的,不过不管那么多啦,思路对了就好- -0 #include<iostream&g ...
- PATH环境变量和CLASSPATH环境变量详解
大凡装过JDK的人都知道要安装完成后要设置环境变量,可是为什么要设置环境变量呢?环境变量有什么作用? 1)PATH详解: 计算机安装JDK之后,输入“javac”“java”之类的命令是不能马上被计算 ...
- Cpp多重继承会产生的问题
多重继承常常被认为是 OOP 中一种复杂且不必要的部分.多重继承面临 crash 的场景并非难以想象,来看下面的例子. 1. 名称冲突 来看以下情况: 如果 Dog 类以及 Bird 类都有一个名为 ...