题目: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. oracle11g中SQL优化(SQL TUNING)新特性之Adaptive Cursor Sharing (ACS)

    1.   ACS简介 Oracle Database 11g提供了Adaptive Cursor Sharing (ACS)功能,以克服以往不该共享的游标被共享的可能性.ACS使用两个新指标:sens ...

  2. angular2使用ng g component navbar创建组件报错

    Error: ELOOP: too many symbolic links encountered, stat 'C:\Users\inn\angulardemo\node_modules\@angu ...

  3. 对比springmvc与struts2

    转载:http://blog.csdn.net/chenleixing/article/details/44570681 1.Struts2是类级别的拦截, 一个类对应一个request上下文,Spr ...

  4. js实现个链表吧

    存储多个元素,最常用的数据结构是数组.但是数组有个一缺点,从数组中添加或移除项的成本很高,因为需要移动元素.链表也可以存储有序的元素集合,但是和数组不同,链表中的元素在内存中不是连续放置的.每个元素存 ...

  5. 微信小程序中的bindTap事件(微信小程序开发QQ群:604788754)

    bindTap对应的绑定事件, 第一个:wx.navigateTo wx.navigateTo({ url:"../content/content" }) 第二个:wx.redir ...

  6. Awk 从入门到放弃(3) —- 内置变量

    转:http://www.zsythink.net/archives/1374 NF :当前行的字段个数 NR:  行号 FNR: 各文件分别计数的行号 RS: 输入行分隔符 ORS:输出行分隔符 内 ...

  7. linux make virtual memory more efficient three components

    Page Cache This is used to speed up access to images and data on disk. As pages are read into memory ...

  8. Flask初级(九)flash与前台交互get详解

    Project name :Flask_Plan templates:templates static:static @app.route('/') def hello_world(): return ...

  9. DevExpress v17.2新版亮点—Analytics Dashboard篇(一)

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

  10. hibernate缓存清除(转)

    文章有点杂,这不是原文,谢谢贡献者 http://www.360doc.com/content/16/0413/16/32415095_550307388.shtml 一.hibernate一级缓存( ...