Description

Input

Output

Sample Input1

1
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

0
50
200
50
150

Sample Input2

1
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

0
2
3
1

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]归程(可持久化并查集,最短路)的更多相关文章

  1. 洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]

    题目传送门 归程 格式难调,题面就不放了. 分析: 之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做. 但是之前做可持久化并查集的时 ...

  2. [NOI2018] 归程 可持久化并查集

    题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个n 个节点.m 条边的无向连通图(节点的编号从 1至 n).我们依次用 l,a描述一条边的长度.海拔. ...

  3. [NOI2018]归程(可持久化并查集,Kruskal重构树)

    解法一: 1.首先想到离线做法:将边和询问从大到小排序,并查集维护连通块以及每个连通块中所有点到1号点的最短距离.$O(n\log n)$ 配合暴力等可以拿到75分. 2.很容易想到在线做法,使用可持 ...

  4. UOJ 393 【NOI2018】归程——可持久化并查集

    题目:http://uoj.ac/problem/393 题解:https://www.cnblogs.com/HocRiser/p/9368067.html 但过不了 UOJ 的 hack 数据.不 ...

  5. 洛谷P4768 [NOI2018]归程(可持久化并查集,最短路)

    闲话 一个蒟蒻,在网络同步赛上进行了这样的表演-- T2组合计数不会,T3字符串数据结构不会,于是爆肝T1 一开始以为整个地图都有车,然后写了2h+的树套树,终于发现样例过不去 然后写可持久化并查集D ...

  6. BZOJ5415[Noi2018]归程——kruskal重构树+倍增+堆优化dijkstra

    题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l,a 描述一条边的长度.海 ...

  7. [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)

    Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...

  8. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  9. bzoj3674 可持久化并查集

    我是萌萌的任意门 可持久化并查集的模板题-- 做法好像很多,可以标号法,可以森林法. 本来有O(mloglogn)的神算法(按秩合并+倍增),然而我这种鶸渣就只会写O(mlog2n)的民科算法--再加 ...

随机推荐

  1. webpack与gulp的区别

    gulp是工具链.构建工具,可以配合各种插件做js压缩,css压缩,less编译 替代手工实现自动化工作 1.构建工具 2.自动化 3.提高效率用 webpack是文件打包工具,可以把项目的各种js. ...

  2. VC++6.0调试:Watch窗口的使用

    #include <stdio.h> #include <windows.h> class AutoExpand { public: AutoExpand(int val, c ...

  3. [日常] Go语言圣经--Channel习题

    练习 8.3: 在netcat3例子中,conn虽然是一个interface类型的值,但是其底层真实类型是*net.TCPConn,代表一个TCP连接.一个TCP连接有读和写两个部分,可以使用Clos ...

  4. java基础-基础语法

    一.标识符 java中对各种变量.方法和类等要素命名的时候使用的字符序列称为标识符. java中标识符的命名规则:1.由字母.数字.下划线(_)以及美元符号($)组成 2.标识符应该以字母或者下划线开 ...

  5. 了解java虚拟机—堆相关参数设置(3)

    堆相关配置 -Xmx 最大堆空间 -Xms 初始堆空间大小,如果初始堆空间耗尽,JVM会对堆空间扩容,其扩展上限为最大堆空间.通常-Xms与-Xmx设置为同样大小,避免扩容造成性能损耗. -Xmn 设 ...

  6. Servlet基础知识点整理

    常用注解 官方文档:https://docs.oracle.com/javaee/7/api/toc.htm WebServlet @WebServlet用于定义一个Servlet,等价于下面的xml ...

  7. Android-远程Service

    http://blog.csdn.net/guolin_blog/article/details/9797169 http://www.jianshu.com/p/eeb2bd59853f 将一个普通 ...

  8. 前端SEO

    一.搜索引擎工作原理 当我们在输入框中输入关键词,点击搜索或查询时,然后得到结果.深究其背后的故事,搜索引擎做了很多事情. 在搜索引擎网站,比如百度,在其后台有一个非常庞大的数据库,里面存储了海量的关 ...

  9. HDU3622(二分+2-SAT)

    Bomb Game Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. Code Signal_练习题_arrayMaxConsecutiveSum

    Given array of integers, find the maximal possible sum of some of its k consecutive elements. Exampl ...