洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]
归程
格式难调,题面就不放了。
分析:
之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做。
但是之前做可持久化并查集的时候感觉掌握的并不熟,还是需要参照别人的题解,不过至少现在对可持久化的理解更深了一步,而且终于这题给调对了。
Code:
//It is made by HolseLee on 23rd Aug 2018
//Luogu.org 4768
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b)
using namespace std; const int N=2e5+,M=8e5+,S=2e7+;
typedef unsigned int ui;
ui T,n,m,Q,K,s,lastans,L,cnt;
ui head[N],nxt[M],to[M],d[M],a[M],b[M],dis[N];
ui rt[M],lc[S],rc[S],dep[S],fa[S],mn[S];
bool vis[N];
struct Node{
ui id,val;
bool operator < (const Node x) const {
return val>x.val;
}
Node(ui x=,ui y=){
id=x,val=y;
}
};
struct Edge{
ui u,v,h;
bool operator < (const Edge x) const {
return h<x.h;
}
Edge(ui x=,ui y=,ui z=){
u=x,v=y,h=z;
}
}e[M];
priority_queue<Node> t; inline ui read()
{
char ch=getchar();ui num=;
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<=''){
num=(num<<)+(num<<)+(ch^);ch=getchar();
}
return num;
} void build(ui &root,ui l,ui r)
{
root=++cnt;
if(l==r){mn[root]=dis[fa[root]=l];return;}
ui mid=(l+r)>>;
build(lc[root],l,mid);
build(rc[root],mid+,r);
} ui ins(ui *root,ui las,ui tag)
{
ui l=,r=n,mid;
while(l!=r){
*root=++cnt,mid=(l+r)>>;
if(tag<=mid)r=mid,rc[*root]=rc[las],root=lc+*root,las=lc[las];
else l=mid+,lc[*root]=lc[las],root=rc+*root,las=rc[las];
}
return *root=++cnt;
} ui find(ui root,ui tag)
{
ui now,l,r,mid;
while(){
now=root,l=,r=n;
while(l!=r){
mid=(l+r)>>;
if(tag<=mid)r=mid,now=lc[now];
else l=mid+,now=rc[now];
}
if(tag==fa[now])break;
tag=fa[now];
}
return now;
} int main()
{
T=read();
ui i,j;
while(T--){
n=read();m=read();
ui x,y,w,cnte=;cnt=;
for(i=;i<=m;++i){
x=read();y=read();
to[++cnte]=y,nxt[cnte]=head[x],head[x]=cnte;
to[++cnte]=x,nxt[cnte]=head[y],head[y]=cnte;
d[cnte]=d[cnte-]=read();
e[i]=Edge(x,y,a[cnte]=a[cnte-]=read());
}
memset(dis,-,(n+)<<);
dis[]=;t.push(Node(,));
while(!t.empty()){
Node now=t.top();t.pop();
if(vis[x=now.id])continue;
vis[x]=true;
for(i=head[x];i;i=nxt[i]){
y=to[i];
if(dis[y]>dis[x]+d[i])
t.push(Node(y,dis[y]=dis[x]+d[i]));
}
}
Q=read(),K=read(),s=read();lastans=;
sort(e+,e+m+);
for(i=;i<=m;++i)b[i]=e[i].h;
b[m+]=s+;
L=unique(b+,b+m+)-b-;
build(rt[L],,n);
for(i=L-,j=m;i;--i){
rt[i]=rt[i+];
for(;j&&e[j].h==b[i];--j){
if((x=find(rt[i],e[j].u))==(y=find(rt[i],e[j].v)))continue;
if(dep[x]>dep[y])swap(x,y);
fa[ins(&rt[i],rt[i],fa[x])]=fa[y];
w=ins(&rt[i],rt[i],fa[y]);
fa[w]=fa[y];mn[w]=Min(mn[x],mn[y]);
dep[w]=dep[y]+(dep[y]==dep[x]);
}
}
for(;Q;--Q){
x=(read()+K*lastans-)%n+;
y=(read()+K*lastans)%(s+);
printf("%u\n",lastans=mn[find(rt[upper_bound(b+,b+L+,y)-b],x)]);
}
memset(vis,,n+);
memset(head,,(n+)<<);
memset(rt,,(L+)<<);
memset(lc,,(cnt+)<<);
memset(rc,,(cnt+)<<);
memset(fa,,(cnt+)<<);
memset(mn,,(cnt+)<<);
memset(dep,,(cnt+)<<);
}
return ;
}
洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]的更多相关文章
- 洛谷P4768 [NOI2018]归程(可持久化并查集,最短路)
闲话 一个蒟蒻,在网络同步赛上进行了这样的表演-- T2组合计数不会,T3字符串数据结构不会,于是爆肝T1 一开始以为整个地图都有车,然后写了2h+的树套树,终于发现样例过不去 然后写可持久化并查集D ...
- 洛谷 P4768 [NOI2018]归程
洛谷 361行代码的由来 数据分治大发好啊- NOI的签到题,可怜我在家打了一下午才搞了80分. 正解应该是kruskal重构树或排序+可持久化并查集. 我就分点来讲暴力80分做法吧(毕竟正解我也没太 ...
- [NOI2018] 归程 可持久化并查集
题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个n 个节点.m 条边的无向连通图(节点的编号从 1至 n).我们依次用 l,a描述一条边的长度.海拔. ...
- BZOJ5415:[NOI2018]归程(可持久化并查集,最短路)
Description Input Output Sample Input1 14 31 2 50 12 3 100 23 4 50 15 0 23 02 14 13 13 2 Sample Outp ...
- [NOI2018]归程(可持久化并查集,Kruskal重构树)
解法一: 1.首先想到离线做法:将边和询问从大到小排序,并查集维护连通块以及每个连通块中所有点到1号点的最短距离.$O(n\log n)$ 配合暴力等可以拿到75分. 2.很容易想到在线做法,使用可持 ...
- [洛谷P4768] [NOI2018]归程 (kruskal重构树模板讲解)
洛谷题目链接:[NOI2018]归程 因为题面复制过来有点炸格式,所以要看题目就点一下链接吧\(qwq\) 题意: 在一张无向图上,每一条边都有一个长度和海拔高度,小\(Y\)的家在\(1\)节点,并 ...
- 洛谷P4768 [NOI2018]归程(Kruskal重构树)
题意 直接看题目吧,不好描述 Sol 考虑暴力做法 首先预处理出从$1$到每个节点的最短路, 对于每次询问,暴力的从这个点BFS,从能走到的点里面取$min$ 考虑如何优化,这里要用到Kruskal重 ...
- 洛谷P4768 [NOI2018]归程(克鲁斯卡尔重构树+最短路)
传送门 前置技能,克鲁斯卡尔重构树 我们按道路的高度建一个最大生成树,然后建好克鲁斯卡尔重构树 那么我们需要知道一颗子树内到1点距离最近是多少(除此之外到子树内任何一个点都不需要代价) 可以一开始直接 ...
- 洛谷$P4768\ [NOI2018]$归程 $kruscal$重构树
正解:$kruscal$重构树 解题报告: 传送门$QwQ$ 语文不好选手没有人权$TT$连题目都看不懂真的要哭了$kk$ 所以先放个题目大意?就说给定一个$n$个点,$m$条边的图,每条边有长度和海 ...
随机推荐
- 学习 C++的用途,(前辈总结)
C++准确说是一门中级语言,介于汇编和高级语言之间吧,要求程序员了解计算机的内部数据存储.个人认为,作为学生还是花功夫学C++,因为<设计模式><数据结构>这些课程基本上还是C ...
- MagicB.0—怎样设置电脑自动关机?
天太晚了,该睡觉了,可是你的东西也许正在下载,软件正在更新,总之电脑还有一些工作没有完成,又不需要你人为的守着,随他去吧!可是电脑已经工作了一天了,它也要休息一下,再者也不能浪费电力资源呀,那么就来使 ...
- 浮动&定位
本文地址:http://www.cnblogs.com/veinyin/p/7606652.html 浮动和定位能够让我们把一些元素放到理想的位置,当然,相比之下 float 只能浮动到左边或右边, ...
- 正则表达式:Python 模块 re 简介
为了使文章更具可读性,本文将正则表达式冗长的 语法介绍 放在了文章的末尾. 一.正则表达式简介 正则表达式(RegExp)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(元字符 ...
- c++树,知道前序和中序求后序遍历
经常有面试题就是知道一棵树的前序遍历和中序遍历让你写出后序遍历,这个慢慢画是能画出来的,但是要很快的弄出来还是要懂原理. 首先说一下三种遍历:所谓的前序后序和中序都是遍历时遍历根节点的顺序.子树的话依 ...
- three.js为何如此奇妙
WebGL是在浏览器中实现三维效果的一套规范,而最初使用WebGL原生的API来写3D程序是一件非常痛苦的事情,在辛苦的付出下WebGL开源框架出现了,其中three.js就是非常优秀的一个,它掩盖了 ...
- King's Quest POJ - 1904 匈牙利算法的思想+tarjan缩点+染色
题目链接:https://cn.vjudge.net/problem/POJ-1904 自己一开始的想法,打算用匈牙利算法实现,找二分图的最大匹配.但是打了打发现,不太好实现.原因如下:匈牙利算法是不 ...
- DNSLOG在渗透测试中的玩法儿
首先了解一下DNS是啥??? DNS(Domain Name System,域名系统),万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读 ...
- python基础===map, reduce, filter的用法
filter的用法: 这还是一个操作表list的内嵌函数'filter' 需要一个函数与一个list它用这个函数来决定哪个项应该被放入过滤结果队列中遍历list中的每一个值,输入到这个函数中如果这个函 ...
- 91.Decode Ways---dp
题目链接:https://leetcode.com/problems/decode-ways/description/ 题目大意:将给出的字符串解码,问有多少种解码方式.解码按照“ABC...Z&qu ...