BZOJ5415:[NOI2018]归程(可持久化并查集,最短路)
Description
Input
Output
Sample Input1
4 3
1 2 50 1
2 3 100 2
3 4 50 1
5 0 2
3 0
2 1
4 1
3 1
3 2
Sample Output1
50
200
50
150
Sample Input2
5 5
1 2 1 2
2 3 1 2
4 3 1 2
5 3 1 2
1 5 2 1
4 1 3
5 1
5 2
2 0
4 0
Sample Output2
HINT
Solution
会了可持久化并查集这题可能会被卡的正解就很好写了……
把边按高度大小从大到小加入,用可持久化并查集记下每一个时刻并查集的联通情况,
同时用持久化的$Min[i]$数组记录$i$点所在的连通块内到点$1$的最近距离。查询的时候二分到对应时刻的并查集直接查询就行了。
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
#define N (200009)
using namespace std; struct Edge{int to,next,len;}edge[N<<];
struct Sgt{int ls,rs,v;};
struct Line
{
int u,v,w,h;
bool operator < (const Line &a) const {return h>a.h;}
}l[N<<];
struct Node
{
int num,dis;
bool operator < (const Node &a) const {return dis>a.dis;}
};
int T,n,m,u,v,w,h,q,k,s,v0,p0,ans;
int dis[N],head[N],num_edge;
bool vis[N];
priority_queue<Node>Q; struct Chairman_Tree
{
Sgt a[N*];
int sgt_num,b[N],Root[N<<]; int Build(int l,int r)
{
int now=++sgt_num;
if (l==r) {a[now].v=b[l]; return now;}
int mid=(l+r)>>;
a[now].ls=Build(l,mid);
a[now].rs=Build(mid+,r);
return now;
}
int Update(int pre,int l,int r,int x,int v)
{
int now=++sgt_num;
a[now].ls=a[pre].ls;
a[now].rs=a[pre].rs;
if (l==r) {a[now].v=v; return now;}
int mid=(l+r)>>;
if (x<=mid) a[now].ls=Update(a[now].ls,l,mid,x,v);
else a[now].rs=Update(a[now].rs,mid+,r,x,v);
return now;
}
int Query(int now,int l,int r,int x)
{
if (l==r) return a[now].v;
int mid=(l+r)>>;
if (x<=mid) return Query(a[now].ls,l,mid,x);
else return Query(a[now].rs,mid+,r,x);
}
}Fa,Dep,Min; inline int read()
{
int x=; char c=getchar();
while (c<'' || c>'') c=getchar();
while (c>='' && c<='') x=x*+c-'', c=getchar();
return x;
} void add(int u,int v,int w)
{
edge[++num_edge].to=v;
edge[num_edge].next=head[u];
edge[num_edge].len=w;
head[u]=num_edge;
} int Find(int x,int t)
{
int fa=Fa.Query(Fa.Root[t],,n,x);
return x==fa?x:Find(fa,t);
} void Dijkstra(int s)
{
memset(dis,0x7f,sizeof(dis));
memset(vis,,sizeof(vis));
dis[s]=;
Q.push((Node){s,});
while (!Q.empty())
{
int x=Q.top().num; Q.pop();
if (vis[x]) continue; vis[x]=;
for (int i=head[x]; i; i=edge[i].next)
if (!vis[edge[i].to] && dis[x]+edge[i].len<dis[edge[i].to])
{
dis[edge[i].to]=dis[x]+edge[i].len;
Q.push((Node){edge[i].to,dis[edge[i].to]});
}
}
} int main()
{
T=read();
while (T--)
{
Fa.sgt_num=Dep.sgt_num=Min.sgt_num=;
memset(head,,sizeof(head)); num_edge=;
ans=;
n=read(); m=read();
for (int i=; i<=m; ++i)
{
u=read(); v=read(); w=read(); h=read();
l[i]=(Line){u,v,w,h};
add(u,v,w); add(v,u,w);
}
Dijkstra();
sort(l+,l+m+);
for (int i=; i<=n; ++i)
Fa.b[i]=i, Dep.b[i]=, Min.b[i]=dis[i];
Fa.Root[]=Fa.Build(,n);;
Dep.Root[]=Dep.Build(,n);
Min.Root[]=Min.Build(,n);
for (int i=; i<=m; ++i)
{
Fa.Root[i]=Fa.Root[i-];
Dep.Root[i]=Dep.Root[i-];
Min.Root[i]=Min.Root[i-];
int fx=Find(l[i].u,i),fy=Find(l[i].v,i);
if (fx==fy) continue;
int dfx=Dep.Query(Dep.Root[i],,n,fx);
int dfy=Dep.Query(Dep.Root[i],,n,fy);
if (dfx>dfy) swap(fx,fy);
Fa.Root[i]=Fa.Update(Fa.Root[i],,n,fx,fy);
int d1=Min.Query(Min.Root[i],,n,fx);
int d2=Min.Query(Min.Root[i],,n,fy);
Min.Root[i]=Min.Update(Min.Root[i],,n,fy,min(d1,d2));
if (dfx==dfy) Dep.Root[i]=Dep.Update(Dep.Root[i],,n,fy,dfy+);
}
q=read(); k=read(); s=read();
for (int i=; i<=q; ++i)
{
v0=read(); p0=read();
v0=(v0+k*ans-)%n+;
p0=(p0+k*ans)%(s+);
int L=,R=m,A=-;
while (L<=R)
{
int mid=(L+R)>>;
if (l[mid].h>p0) A=mid,L=mid+;
else R=mid-;
}
if (A==-)
{
printf("%d\n",dis[v0]);
ans=dis[v0]; continue;
}
int fx=Find(v0,A);
ans=Min.Query(Min.Root[A],,n,fx);
printf("%d\n",ans);
}
}
}
BZOJ5415:[NOI2018]归程(可持久化并查集,最短路)的更多相关文章
- 洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]
题目传送门 归程 格式难调,题面就不放了. 分析: 之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做. 但是之前做可持久化并查集的时 ...
- [NOI2018] 归程 可持久化并查集
题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个n 个节点.m 条边的无向连通图(节点的编号从 1至 n).我们依次用 l,a描述一条边的长度.海拔. ...
- [NOI2018]归程(可持久化并查集,Kruskal重构树)
解法一: 1.首先想到离线做法:将边和询问从大到小排序,并查集维护连通块以及每个连通块中所有点到1号点的最短距离.$O(n\log n)$ 配合暴力等可以拿到75分. 2.很容易想到在线做法,使用可持 ...
- UOJ 393 【NOI2018】归程——可持久化并查集
题目:http://uoj.ac/problem/393 题解:https://www.cnblogs.com/HocRiser/p/9368067.html 但过不了 UOJ 的 hack 数据.不 ...
- 洛谷P4768 [NOI2018]归程(可持久化并查集,最短路)
闲话 一个蒟蒻,在网络同步赛上进行了这样的表演-- T2组合计数不会,T3字符串数据结构不会,于是爆肝T1 一开始以为整个地图都有车,然后写了2h+的树套树,终于发现样例过不去 然后写可持久化并查集D ...
- BZOJ5415[Noi2018]归程——kruskal重构树+倍增+堆优化dijkstra
题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l,a 描述一条边的长度.海 ...
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
- bzoj3674 可持久化并查集
我是萌萌的任意门 可持久化并查集的模板题-- 做法好像很多,可以标号法,可以森林法. 本来有O(mloglogn)的神算法(按秩合并+倍增),然而我这种鶸渣就只会写O(mlog2n)的民科算法--再加 ...
随机推荐
- Spring基础(5): 构造函数注入无法处理循环依赖
public class Person{ public Leader leader; public Person(Leader l){ this.leader= l; } } public class ...
- VS 通用产品密钥
BWG7X-J98B3-W34RT-33B3R-JVYW9 HMGNV-WCYXV-X7G9W-YCX63-B98R2 HM6NR-QXX7C-DFW2Y-8B82K-WTYJV
- Mybatis注解开发模糊查询
Mybatis注解开发模糊查询 一般在使用mybatis时都是采用xml文件保存sql语句 这篇文章讲一下在使用mybatis的注解开发时,如何进行模糊查询 模糊查询语句写法(在@Select注解中) ...
- python-模板方法模式
源码地址:https://github.com/weilanhanf/PythonDesignPatterns 说明: 模板方法模式时行为模式中比较简单的设计模式之一.模板方法关注这样的一类行为:该类 ...
- php实现同一时间内一个账户只允许在一个终端登陆
在账户表的基础上,我新建了一个账户account_session表,用来记录登录账户的account_id和最新一次登录成功用户的session_id,然后首先要修改登录方法:每次登录成功后,要将登录 ...
- org.springframework.transaction.CannotCreateTransactionException Could not open
org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for ...
- 阿里云服务器(ECS)从购买到配置NodeJS环境
本人入门级前端,对服务器不熟悉,这是自己摸索的过程,可能会有错误! 1.购买 阿里云服务器有个活动是新用户前六个月可以免费试用,但是每天早上发放一定的名额,但为了方便,我买了18RMB的捆绑套餐,也是 ...
- js-ES6学习笔记-Proxy(2)
1.has方法用来拦截HasProperty操作,即判断对象是否具有某个属性时,这个方法会生效.典型的操作就是in运算符. var handler = { has (target, key) { if ...
- Express 框架
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具.使用 Express 可以快速地搭建一个完整功能的网站 ...
- OpenCV多版本管理
OpenCV在Ubuntu下经常会安装多个版本,比如默认版本,自己安装的,ros安装的等等.有时候需要给程序指定某个OpenCV版本,网上有一些方法,但还是会遇到很多问题. 这里提供一种选择,即指定O ...