这道题很简单的连剖+分类讨论,但是SDOI Round2要来了,不会手动栈怎么办呢?只好用一下这道题练习一下手动栈了,结果调了一天多QwQ

链剖的第一个dfs用bfs水过就行,但是我自以为是地把倍增写错了,坑了好久啊QAQ

这道题因为要询问子树,连剖的第二个dfs就不能再用bfs水过了,只能强行手动栈。

一开始拍小数据拍出了好多错,改过来后拍了无数组极限数据也拍不出来,因为构造的极限数据太弱了(偷懒构造u<v)根本无法暴露倍增的漏洞啊!!!

手残错误毁一生,写代码时不要自以为是。希望SD省选能够给我们一个更好的编程环境和评测环境(NOILinux恐怕是奢望吧)

#include<stack>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100003;
const int inf = 0x7fffffff;
void read(int &k) {
k = 0; int fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = (k << 1) + (k << 3) + c - '0';
k = k * fh;
} struct node {int nxt, to;} E[N << 1];
int n, m, point[N], cnt = 0, pos[N], wt[N], deep[N];
int lazy[N * 8], mn[N * 8], top[N], sz[N], f[N][18], root, a[N], son[N]; void ins(int x, int y) {E[++cnt] = (node) {point[x], y}; point[x] = cnt;}
stack <int> S;
int qu[N];
void _() {
int p = 0, q = 1; qu[1] = 1;
while (p != q) {
int u = qu[++p];
for(int tmp = point[u]; tmp; tmp = E[tmp].nxt)
if (E[tmp].to != f[u][0])
f[E[tmp].to][0] = u, deep[E[tmp].to] = deep[u] + 1, qu[++q] = E[tmp].to;
}
for(int i = q; i >= 1; --i) {
int u = qu[i], fa = f[u][0];
++sz[u];
sz[fa] += sz[u];
if (sz[u] > sz[son[fa]]) son[fa] = u;
}
for(int j = 1; j <= 17; ++j)
for(int i = 1; i <= n; ++i)
f[i][j] = f[f[i][j - 1]][j - 1];
}
void __() {
top[1] = 1; cnt = 0;
S.push(1);
while (!S.empty()) {
int u = S.top(); S.pop();
pos[++cnt] = u; wt[u] = cnt;
for(int tmp = point[u]; tmp; tmp = E[tmp].nxt)
if (E[tmp].to != f[u][0] && E[tmp].to != son[u])
top[E[tmp].to] = E[tmp].to, S.push(E[tmp].to);
if (son[u]) {top[son[u]] = top[u]; S.push(son[u]);}
}
}
/* 下面是正确的人工栈模板,完美模拟dfs,但是我学会它不到5小时我就用bfs把它淘汰了
void _() {
S.push(Data(1, point[1]));
sz[1] = 1;
while (!S.empty()) {
int x = S.top().x, y = S.top().y; S.pop();
if (y) {
S.push(Data(x, E[y].nxt));
int v = E[y].to;
if (v != f[x][0]) {
f[v][0] = x;
sz[v] = 1;
deep[v] = deep[x] + 1;
for(int i = 1; i <= 17; ++i) {f[v][i] = f[f[v][i - 1]][i - 1]; if (f[v][i] == 0) break;}
S.push(Data(v, point[v]));
}
} else {
if (!S.empty()) {
sz[S.top().x] += sz[x];
if (sz[x] > sz[son[S.top().x]]) son[S.top().x] = x;
}
}
}
}*/ void pushdown(int rt) {
if (lazy[rt]) {
mn[rt << 1] = mn[rt << 1 | 1] = lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
lazy[rt] = 0;
}
}
void pushup(int rt) {mn[rt] = min(mn[rt << 1], mn[rt << 1 | 1]);}
void Build(int rt, int l, int r) {
if (l == r) {mn[rt] = a[pos[l]]; mn[rt << 1] = mn[rt << 1 | 1] = inf; return;}
int mid = (l + r) >> 1;
Build(rt << 1, l, mid);
Build(rt << 1 | 1, mid + 1, r);
pushup(rt);
}
void add(int rt, int l, int r, int L, int R, int x) {
if (L <= l && r <= R) {lazy[rt] = x; mn[rt] = x; return;}
int mid = (l + r) >> 1;
pushdown(rt);
if (L <= mid) add(rt << 1, l, mid, L, R, x);
if (R > mid) add(rt << 1 | 1, mid + 1, r, L, R, x);
pushup(rt);
}
void Add(int x, int y, int z) {
for(; top[x] != top[y]; x = f[top[x]][0]) {
if (deep[top[x]] < deep[top[y]]) swap(x, y);
add(1, 1, n, wt[top[x]], wt[x], z);
}
if (deep[x] < deep[y]) swap(x, y);
add(1, 1, n, wt[y], wt[x], z);
}
int QQ(int rt, int l, int r, int L, int R) {
if (L <= l && r <= R) return mn[rt];
int mid = (l + r) >> 1, s = inf;
pushdown(rt);
if (L <= mid) s = min(s, QQ(rt << 1, l, mid, L, R));
if (R > mid) s = min(s, QQ(rt << 1 | 1, mid + 1, r, L, R));
return s;
}
int Q(int L, int R) {
if (L > n || R < 1 || L > R) return inf;
return QQ(1, 1, n, L, R);
} int lower;
int LCA(int x, int y) {
if (deep[x] < deep[y]) return 1;
for(int i = 16; i >= 0; --i) if (deep[f[x][i]] > deep[y]) x = f[x][i];
lower = x;
return f[x][0] != y;
} int main() {
read(n); read(m);
int u, v, op, x;
for(int i = 1; i < n; ++i) {
read(u); read(v);
ins(u, v); ins(v, u);
} _();
__(); for(int i = 1; i <= n; ++i) read(a[i]); Build(1, 1, n); read(root);
for(int i = 1; i <= m; ++i) {
read(op);
switch (op) {
case 1:
read(root);
break;
case 2:
read(u); read(v); read(x);
Add(u, v, x);
break;
case 3:
read(u);
if (root == u)
printf("%d\n", Q(1, n));
else
if (LCA(root, u)) {
printf("%d\n", Q(wt[u], wt[u] + sz[u] - 1));
} else {
v = min(Q(1, wt[lower] - 1), Q(wt[lower] + sz[lower], n));
printf("%d\n", v);
}
break;
}
} return 0;
}

注释掉了能够完美模拟dfs但并没有什么用的手动栈= =

【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 - 遥远的国度

    原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3083 说话间又一个多月过去了..该来除除草了,每天都是训练.没效率,训练.没效率..省选考 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 详细说说 Google Test Certified 的各级——Level 2,3

    转载请联系作者,谢谢!   No releases with red tests基于Level1搭建的持续集成,持续发布选用的CL(changelist)就可以取自CI系统最后跑通的CL,因为持续集成 ...

  2. ural Infernal Work

    Infernal Work Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Descr ...

  3. [转帖]VS选中某个代码报错修补

    如题,此问题,出现在xp sp3的情况比较多,至少在我常用的两台电脑上面是这样子的, 完整的安装了VS2010之后,在编写代码的时候,只要用鼠标拖选代码或者双击,选中某个代码,IDE就自动报错 重启 ...

  4. Java daemon thread 守护线程

    守护线程与普通线程写法上基本么啥区别,在启动线程前, 调用线程对象的方法setDaemon(true),则可以将其设置为守护线程. 守护线程使用的情况较少,但并非无用,举例来说,JVM的垃圾回收.内存 ...

  5. windows Server 2008各版本区别详解

    Windows Server 2008 是专为强化下一代网络.应用程序和 Web 服务的功能而设计,是有史以来最先进的 Windows Server 操作系统.拥有 Windows Server 20 ...

  6. Asp.net,C# 纯数字加密解密字符串

    也就是说加密后的数据不再是:N8lAaHMFtSAQgaf3+RUFng== 希望encryptedString是"1203877893704809384098328409234923840 ...

  7. addShutdownHook的用法

    addShutdownHook作为一个正常关闭Java程序的途径,其实是非常有用的. 有JDK文档可知,当程序正常退出,或者为响应用户中断而终止虚拟机的时候,就会调用里面的线程,来作最后的退出处理. ...

  8. python生成汉字图片字库

    最近做文档识别方面的项目,做汉字识别需要建立字库,在网上找了各种OCR,感觉都不好,这方面的技术应该比较成熟了,OCR的软件很多,但没有找到几篇有含金量量的论文,也没有看到哪位大牛公开字库,我用pyg ...

  9. FineUI v4.0.3 (beta) 和 FineUI v3.3.3 发布了!

    关于FineUI基于 ExtJS 的开源 ASP.NET 控件库 FineUI的使命创建 No JavaScript,No CSS,No UpdatePanel,No ViewState,No Web ...

  10. 浅谈WCF的三种通信模式:请求响应模式、数据报模式和双工通讯模式

    一: WCF的服务端与客户端在通信时有三种模式:请求响应模式.数据报模式和双工通讯模式. 说一下基本知识,  1.如果想要将当前接口作为wcf服务器,则一定要加上[ServiceContract] 契 ...