题目:http://uoj.ac/problem/393

题解:https://www.cnblogs.com/HocRiser/p/9368067.html

但过不了 UOJ 的 hack 数据。不知道是哪里出错。之后再管吧。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define mkp make_pair
#define pb push_back
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
const int N=2e5+,M=4e5+,INF=2e9+;
int n,m,hd[N],xnt,to[M<<],nxt[M<<],w[M<<],dis[N];
int fa[N],ht[N],mn[N],dep[N]; bool vis[N];
struct Ed{
int x,y,h;
Ed(int x=,int y=,int h=):x(x),y(y),h(h) {}
bool operator< (const Ed &b)const
{return h>b.h;}
}ed[M];
struct Node{
int h,v;
Node(int h=,int v=):h(h),v(v) {}
bool operator< (const Node &b)const
{return h>b.h;}
};
priority_queue<pair<int,int> > q;
vector<Node> Mn[N];
vector<Node>::iterator it;
void add(int x,int y,int z){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;w[xnt]=z;}
void dj()
{
memset(vis,,sizeof vis);
for(int i=;i<=n;i++)dis[i]=INF;
q.push(mkp(,));
while(q.size())
{
int k=q.top().second; q.pop();
if(vis[k])continue; vis[k]=;
for(int i=hd[k],v;i;i=nxt[i])
if(dis[v=to[i]]>dis[k]+w[i])
{
dis[v]=dis[k]+w[i];
q.push(mkp(-dis[v],v));
}
}
}
int fnd(int u,int p)
{
while(fa[u]!=u&&ht[u]>p)u=fa[u];
return u;
}
int fnd2(int u,int p)
{
it=--lower_bound(Mn[u].begin(),Mn[u].end(),Node(p,));
return (*it).v;
}
int main()
{
int T=rdn();
while(T--)
{
n=rdn();m=rdn();
xnt=; memset(hd,,sizeof hd);
for(int i=,u,v,l,h;i<=m;i++)
{
u=rdn();v=rdn();l=rdn();h=rdn();
add(u,v,l);add(v,u,l);
ed[i]=Ed(u,v,h);
}
dj(); sort(ed+,ed+m+);
for(int i=;i<=n;i++)
{
Mn[i].clear();
Mn[i].pb(Node(INF,mn[i]=dis[i]));
fa[i]=i; dep[i]=;
}
for(int i=;i<=m;i++)
{
int u=fnd(ed[i].x,), v=fnd(ed[i].y,);
if(u==v)continue;
if(dep[u]>dep[v])swap(u,v);
if(dep[u]==dep[v])dep[v]++;
fa[u]=v; ht[u]=ed[i].h;
if(mn[u]<mn[v])
Mn[v].pb(Node(ed[i].h,mn[v]=mn[u]));
}
int Q=rdn(),K=rdn(),S=rdn()+,ans=;
for(int i=,u,p;i<=Q;i++)
{
u=(rdn()+(K?ans:)-)%n+;
p=(rdn()+(K?ans:))%S;
u=fnd(u,p); ans=fnd2(u,p);
printf("%d\n",ans);
}
}
return ;
}

还写了可持久化并查集的。在 UOJ 上TLE最后两个点,在 LOJ 上能过。

注意每次 tot=0 。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define mkp make_pair
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mn(int a,int b){return a<b?a:b;}
const int N=2e5+,M=4e5+,K=*M,INF=;
int n,m,hd[N],xnt,to[M<<],nxt[M<<],w[M<<],dis[N];
int tp[M],rt[M],ht[M]; bool vis[N];
int tot,ls[K],rs[K],vl[K],dep[K],mn[K];
struct Ed{
int x,y,h;
Ed(int x=,int y=,int h=):x(x),y(y),h(h) {}
bool operator< (const Ed &b)const
{return h>b.h;}
}ed[M];
priority_queue<pair<int,int> > q;
void add(int x,int y,int z)
{to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;w[xnt]=z;}
void dj()
{
memset(vis,,sizeof vis);
for(int i=;i<=n;i++)dis[i]=INF;
q.push(mkp(,));
while(q.size())
{
int k=q.top().second; q.pop();
if(vis[k])continue; vis[k]=;
for(int i=hd[k],v;i;i=nxt[i])
if(dis[v=to[i]]>dis[k]+w[i])
dis[v]=dis[k]+w[i], q.push(mkp(-dis[v],v));
}
}
void build(int l,int r,int& cr)
{
cr=++tot;
if(l==r){vl[cr]=l;dep[cr]=;mn[cr]=dis[l];return;}
int mid=l+r>>;
build(l,mid,ls[cr]); build(mid+,r,rs[cr]);
}
void ins(int l,int r,int& cr,int pr,int p)
{
cr=++tot;ls[cr]=ls[pr];rs[cr]=rs[pr];
if(l==r)
{
vl[cr]=vl[pr];dep[cr]=dep[pr];
mn[cr]=mn[pr];return;
}
int mid=l+r>>;
if(p<=mid)ins(l,mid,ls[cr],ls[pr],p);
else ins(mid+,r,rs[cr],rs[pr],p);
}
int qry(int l,int r,int cr,int p)
{
if(l==r)return cr; int mid=l+r>>;
if(p<=mid)return qry(l,mid,ls[cr],p);
else return qry(mid+,r,rs[cr],p);
}
int fnd(int nw,int a)
{
int fa=qry(,n,nw,a);
if(vl[fa]==a)return fa;
return fnd(nw,vl[fa]);
}
int fnd2(int p)
{
int l=,r=m,ret=;//l=0
while(l<=r)
{
int mid=l+r>>;
if(ht[mid]>p)ret=mid,l=mid+;
else r=mid-;
}
return ret;
}
int main()
{
int T=rdn();
while(T--)
{
n=rdn();m=rdn();
xnt=; memset(hd,,sizeof hd);
for(int i=,u,v,l,a;i<=m;i++)
{
u=rdn();v=rdn();l=rdn();a=rdn();
add(u,v,l); add(v,u,l);
ed[i]=Ed(u,v,a); tp[i]=a;
}
dj(); int Q=rdn(),K=rdn(),S=rdn();
tot=;//////
sort(ed+,ed+m+); build(,n,rt[]);
/*
for(int i=1,u,v;i<=m;i++)
{
rt[i]=rt[i-1];
u=fnd(rt[i],ed[i].x); v=fnd(rt[i],ed[i].y);
if(vl[u]==vl[v])continue;
if(dep[u]>dep[v])swap(u,v);
ins(1,n,rt[i],rt[i],vl[u]);u=tot;
ins(1,n,rt[i],rt[i],vl[v]);v=tot;
vl[u]=vl[v]; mn[v]=Mn(mn[v],mn[u]);
if(dep[u]==dep[v])dep[v]++;
}
*/
int lm=m; m=;
for(int i=,u,v;i<=lm;m++)
{
rt[m]=rt[m-]; ht[m]=ed[i].h;
while(i<=lm&&ed[i].h==ht[m])
{
u=fnd(rt[m],ed[i].x); v=fnd(rt[m],ed[i].y);
i++; if(vl[u]==vl[v])continue;
if(dep[u]>dep[v])swap(u,v);
ins(,n,rt[m],rt[m],vl[u]);u=tot;
ins(,n,rt[m],rt[m],vl[v]);v=tot;
vl[u]=vl[v]; mn[v]=Mn(mn[v],mn[u]);
if(dep[u]==dep[v])dep[v]++;
}
}
int ans=; S++; m--; ht[]=INF;//
for(int i=,v,p;i<=Q;i++)
{
v=(rdn()+(K?ans:)-)%n+;
p=(rdn()+(K?ans:))%S; p=fnd2(p);
//p=lower_bound(ed+1,ed+m+1,Ed(0,0,p))-ed-1;
v=fnd(rt[p],v); ans=mn[v];
printf("%d\n",ans);
}
}
return ;
}

UOJ 393 【NOI2018】归程——可持久化并查集的更多相关文章

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

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

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

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

  3. 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 ...

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

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

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

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

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

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

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

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

  8. bzoj3674 可持久化并查集

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

  9. 【BZOJ3673】&&【BZOJ3674】: 可持久化并查集 by zky 可持久化线段树

    没什么好说的. 可持久化线段树,叶子节点存放父亲信息,注意可以规定编号小的为父亲. Q:不是很清楚空间开多大,每次询问父亲操作后修改的节点个数是不确定的.. #include<bits/stdc ...

随机推荐

  1. WinForm下的TabControl控件

    一.TabControl控件介绍 TabControl实现的具体效果: 在实际工作中,我是这么用TabControl控件,实现切换页面效果.比如要实现某个界面进行操作,然后还要查看一下日志,就可以使用 ...

  2. 装载问题(load)

    装载问题(load) 问题描述: 有一批共n 个集装箱要装上艘载重量为c 的轮船,其中集装箱i 的重量为wi.找出一种最 优装载方案,将轮船尽可能装满,即在装载体积不受限制的情况下,将尽可能重的集装箱 ...

  3. redis 处理命令的过程

    redis版本:redis-3.2.9 在客户端输入 set name zhang,调试redis服务器,得到调用栈如下: 在dictReplace中加了断点,结果跳出来4个线程,redis还是单进程 ...

  4. Java多线程的同步控制记录

    Java多线程的同步控制记录 一.重入锁 重入锁完全可以代替 synchronized 关键字.在JDK 1.5 早期版本,重入锁的性能优于 synchronized.JDK 1.6 开始,对于 sy ...

  5. 为什么要使用encodeURL转换URL编码?

    参考: https://www.cnblogs.com/haitao-fan/p/3399018.html http://www.ruanyifeng.com/blog/2010/02/url_enc ...

  6. npm install mysql --save-dev

    npm install X: 会把X包安装到node_modules目录中 不会修改package.json 之后运行npm install命令时,不会自动安装X npm install X –sav ...

  7. hdu 1556 Color the ball (线段树+代码详解)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  8. DevExpress v17.2新版亮点—.NET Reporting篇(二)

    用户界面套包DevExpress v17.2日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了.NET Reporting v17.2 的新功能,快来下载试用新版本! 支持AS ...

  9. 基于资源名的MVC权限控制

    在程序复杂程度不断上升的过程中,无可避免需要触碰到权限控制,而权限控制又与业务逻辑紧紧相关,市场上出现了大量的权限控制产品,而程序的开发,讲究去繁化简的抽象,在我的开发过程中,逐渐发现程序的权限控制核 ...

  10. golang多进程测试代码

    package main import ( "fmt" "runtime" ) func test(c chan bool, n int) { x := 0 f ...