3083: 遥远的国度

2024-03-27 04:48
文章标签 国度 遥远 3083

本文主要是介绍3083: 遥远的国度,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

唔,没初始化 wa了一次…
思路很一眼。
就是说 考虑 树剖
如果 查询点是首都的祖先,那么查询点构成的子树就是 整个树除了 查询点包含 首都的儿子以外所有点。
那么 知道一个子树在树剖上是连续一段区间, 即 现在需要求 出 包含首都的那棵子树的根,
用类似倍增lca的方法即可。
对于查询点不是首都的祖先的情况,答案直接为 查询点这棵子树 的答案
搞定
c++代码如下:

#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x ; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x ; i >= y; -- i)
using namespace std;
typedef long long ll;
template<typename T>inline void read(T&x)
{char c;int sign = 1;x = 0;do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));x *= sign;
}const int N = 1e5+50;
int head[N],to[N<<1],nxt[N<<1],tot;
int n,m,w[N];inline void add(int x,int y)
{to[tot] = y;nxt[tot] = head[x];head[x] = tot++;
}int sz,id[N],idx[N];
struct Segment_tree
{int val[N<<2],lzy[N<<2];void build(int id,int l,int r){if(l == r) return void(val[id] = w[idx[l]]);int mid = l + r >> 1;build(id<<1,l,mid); build(id<<1|1,mid+1,r);val[id] = min(val[id<<1],val[id<<1|1]);}int find(int id,int l,int r,int L,int R){if(l == L && r == R) return val[id];    if(lzy[id]) return lzy[id];int mid = l + r >> 1;if(R <= mid) return find(id<<1,l,mid,L,R);if(L > mid) return find(id<<1|1,mid+1,r,L,R);return min(find(id<<1,l,mid,L,mid),find(id<<1|1,mid+1,r,mid+1,R));}inline void put_down(int id){if(!lzy[id]) return;val[id<<1] = lzy[id<<1] = lzy[id];val[id<<1|1] = lzy[id<<1|1] = lzy[id];lzy[id] = 0;}void update(int id,int l,int r,int L,int R,int w){if(l == L && r == R) return void(val[id]=lzy[id]=w);int mid = l + r >> 1;put_down(id);if(R <= mid) update(id<<1,l,mid,L,R,w);else if(L > mid) update(id<<1|1,mid+1,r,L,R,w);else update(id<<1,l,mid,L,mid,w),update(id<<1|1,mid+1,r,mid+1,R,w);val[id] = min(val[id<<1],val[id<<1|1]);}
}seg;int p[N][21],hson[N],size[N],deep[N],top[N];void dfs1(int x)
{size[x] = 1;for(register int i = head[x];~i;i=nxt[i])if(to[i] != p[x][0]){deep[to[i]] = deep[x] + 1;p[to[i]][0] = x;dfs1(to[i]);size[x] += size[to[i]];if(size[hson[x]] < size[to[i]])hson[x] = to[i];}
}void dfs2(int x,int t)
{top[x] = t; id[x] = ++sz; idx[sz] = x;if(hson[x]) dfs2(hson[x],t);for(register int i = head[x];~i;i=nxt[i])if(to[i]!=hson[x]&&to[i]!=p[x][0])dfs2(to[i],to[i]);
}inline void update(int u,int v,int w)
{while(top[u] != top[v]){if(deep[top[u]] < deep[top[v]]) swap(u,v);seg.update(1,1,n,id[top[u]],id[u],w);u = p[top[u]][0];}if(deep[u] < deep[v]) swap(u,v);seg.update(1,1,n,id[v],id[u],w);
}int q;
inline bool check(int x,int rt)
{if(deep[rt] < deep[x]) return true;repd(i,20,0)if(deep[rt] - (1<<i) > deep[x])rt = p[rt][i];if(p[rt][0] != x) return true;q = rt;return false;
}int rt;
int main()
{memset(head,-1,sizeof head);read(n); read(m);rep(i,2,n){int u,v;read(u); read(v);add(u,v); add(v,u);}rep(i,1,n) read(w[i]);read(rt);dfs1(1);dfs2(1,1);rep(j,1,20)rep(i,1,n)p[i][j] = p[p[i][j-1]][j-1];seg.build(1,1,n);   int op,x;rep(i,1,m){read(op);if(op == 1) read(rt);if(op == 2){int u,v,w;read(u); read(v); read(w);update(u,v,w);}if(op == 3){read(x);if(x == rt) printf("%d\n",seg.val[1]);else if(check(x,rt)){printf("%d\n",seg.find(1,1,n,id[x],id[x]+size[x]-1));}else{printf("%d\n",min(id[q]==1?INT_MAX:seg.find(1,1,n,1,id[q]-1),id[q]+size[q]-1==n?INT_MAX:seg.find(1,1,n,id[q]+size[q],n)));}}}return 0;
}

这篇关于3083: 遥远的国度的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/850983

相关文章

BZOJ 1006 神奇的国度 弦图最小染色 MCS算法

给定一个弦图,求最小染色 参考cdq的弦图与区间图论文 http://wenku.baidu.com/view/07f4be196c175f0e7cd13784.html http://tieba.baidu.com/p/2891159900 http://www.cnblogs.com/zhj5chengfeng/p/3279649.html

Nyoj 20 吝啬的国度[dfs]

题目链接:点击打开链接 开始的时候,思路是有的。就是纯粹的深搜。当然广搜也是可以的。本博客仅讲解深搜用法。 由于这是一棵生成树,所以,从出发点到达每个结点的路径是唯一的。 直接深搜就可以。 需要注意的一点是,每个路径都是无向的。为此在陪送了一次WA。 #include <cstdio>#include <cstring>#include <stack>#include <v

华硕ROG玩家国度安装Ubuntu20.04,安装过程一直卡着不动,以及快捷键不能用,不能调节键盘亮度等问题的解决办法,另附上安装Ubuntu18.04的方法

华硕ROG玩家国度是一个游戏本,用的硬件都比较新,所以安装Ubuntu18.04、Ubuntu20.04、Ubuntu20.1基本上都会面临一些问题,包括驱动或者安装过程不能进行等问题。 我一共测试了上述三个版本的系统,最终选择了Ubuntu20.04的系统。主要原因是Ubuntu18.04比较旧,不能安装rog的内核驱动,所以rog的快捷键也就无法使用(也有办法解决这些问题,但是比较麻烦!),

NYOJ 题目20吝啬的国度(DFS)

吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来。现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号城市(假设你不走重复的路)。   输入 第一行输入一个整数M表示测试数据共有M(1<=

nyoj-20--吝啬的国度-DFS+vector

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=20 #include<stdio.h>#include<string.h>#include<vector>using namespace std;vector<int> G[100005];int s[100005];int vis[100005];void dfs(i

poj 3083 深搜+广搜

如题:http://poj.org/problem?id=3083         今天可是元旦,好想找妹纸出去玩啊...算了 还是敲代码吧............~~~~       题目给出一个迷宫,'#'是墙,不能走,‘.’是路,能走,要从起点‘S’走到终点'E'。      题目要分别输出3中走法的步数,第一种左转优先,第二种右转优先。注意,如果是第一种,

吝啬的国度--无向图,广度优先遍历,内存爆掉了

地址:http://acm.nyist.net/JudgeOnline/problem.php?pid=20 吝啬的国度 时间限制: 1000 ms  |  内存限制: 65535 KB 难度: 3 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来。现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经

POJ 3083 *** Children of the Candy Corn

题意:走迷宫,求一直靠墙向左走和靠墙向右走以及最短路径的长度。 想法:我真是智商感人,写个dfs和bfs都错误多多。一直也没理解到靠墙向左走和靠墙向右走是怎么回事,原来靠墙左走是顺时针走,靠墙右走为逆时针,同时下一点的初始行走方向依赖于前一步到达该点的行走方向。同时从起点到终点向右走等同于从终点到起点向左走。对了,以后保持每天至少ac两道题吧。 代码如下: <div>#

POJ 3083--Children of the Candy Corn

题目:这是题目 题意:一个迷宫,从S点走到E点,求一直靠墙向左走和靠墙向右走以及随便走的最短路, 保证数据的合法性,一定会有路。 定义的方向: int x[4] = {0, -1, 0, 1};//左 上 右 下int y[4] = {-1, 0, 1, 0}; 思路:要求靠墙向左走和靠墙向右走,用DFS,求随便走最短路用BFS。该题的比较难的地方是处理方向。

3083. 字符串及其反转中是否存在同一子字符串

说在前面 🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是出于什么原因,算法学习需要持续保持。 题目描述 给你一个字符串 s ,请你判断字符串 s 是否存在一个长度为 2 的子字符串,在其反转后的字符串中也出现。 如果存在这样的子字符串,返回 true;如果不存在,返回 false 。 示例 1: **输入:** s = "leetcode"**输出: