首先,由于题目强制在线,所以需要用到可持久化并查集去维护动态的并查集,去动态的记录fa数组。
跑最短路要dijkstra
对于高度要离散化,否则点太多
细节特别多。。。。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5+5;
int t,n,q,cnt,k,s,m,tot,dep[maxn<<5],root[maxn],head[maxn],dis[maxn],vis[maxn],b[maxn<<1];
struct edge
{
int to,nxt,len;
}G[maxn<<1];
struct eedge
{
int from,to,hei;
bool operator < (eedge other) const
{
return hei<other.hei;
}
}e[maxn<<1];
struct node
{
int u,d;
bool operator < (node other) const
{
return d>other.d;
}
};
priority_queue <node> que;
void add(int x,int y,int z)
{
G[++tot].nxt=head[x];
G[tot].to=y;
G[tot].len=z;
head[x]=tot;
}
void dijkstra()
{
memset(dis,0x3f,(n+1)<<2);
memset(vis,0,(n+1)<<2);
que.push((node){1,0});
dis[1]=0;
while(!que.empty())
{
node cur=que.top(); que.pop();
if(vis[cur.u]) continue;
vis[cur.u]=1;
for(int i=head[cur.u];i;i=G[i].nxt)
if(dis[G[i].to]>dis[cur.u]+G[i].len)
que.push((node){G[i].to,dis[G[i].to]=dis[cur.u]+G[i].len});
}
}
int lc[maxn<<5],rc[maxn<<5],mn[maxn<<5],f[maxn<<5];
void build(int &u,int l,int r)
{
u=++cnt;
if(l==r)
{
mn[u]=dis[f[u]=l];
return;
}
int mid=(l+r)>>1;
build(lc[u],l,mid);
build(rc[u],mid+1,r);
}
int getf(int rt,int t)
{
int u,l,r;
while(1)
{
u=rt,l=1,r=n;
while(l!=r)
{
int mid=(l+r)>>1;
if(t<=mid) r=mid,u=lc[u];
else l=mid+1,u=rc[u];
}
if(t==f[u]) break;
t=f[u];
}
return u;
}
int insert(int *u,int v,int t)
{
int l=1,r=n;
while(l!=r)
{
*u=++cnt;
int m=(l+r)>>1;
if(t<=m)r=m,rc[*u]=rc[v],u=lc+*u,v=lc[v];
else l=m+1,lc[*u]=lc[v],u=rc+*u,v=rc[v];
}
return *u=++cnt;
}
int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
int t; scanf("%d",&t);
while(t--)
{
cnt=tot=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v,z,zz;scanf("%d%d%d%d",&u,&v,&z,&zz);
add(u,v,z); add(v,u,z);
e[i]=((eedge){u,v,zz});
}
dijkstra();
sort(e+1,e+m+1);
for(int i=1;i<=m;i++) b[i]=e[i].hei;
scanf("%d%d%d",&q,&k,&s);
b[m+1]=s+1; int L=unique(b+1,b+m+2)-b-1;
build(root[L],1,n);
int j,i;
for(i=L-1,j=m;i;i--)
{
root[i]=root[i+1];
for(;j&&e[j].hei==b[i];j--)
{
int fu=getf(root[i],e[j].from),fv=getf(root[i],e[j].to);
if(fu==fv) continue;
if(dep[fu]>dep[fv]) swap(fu,fv);
f[insert(&root[i],root[i],f[fu])]=f[fv];
int tmp=insert(&root[i],root[i],f[fv]);
f[tmp]=f[fv];
mn[tmp]=min(mn[fu],mn[fv]);
dep[tmp]=dep[fv]+(dep[fu]==dep[fv]);
}
}
int lans=0;
while(q--)
{
int v,u; scanf("%d%d",&v,&u);
v=(v+k*lans-1)%n+1;
u=(u+k*lans)%(s+1);
printf("%d\n",lans=mn[getf(root[upper_bound(b+1,b+L+1,u)-b],v)]);
}
for(int i=1;i<=cnt;i++)
f[i]=lc[i]=rc[i]=mn[i]=dep[i]=0;
for(int i=1;i<=n;i++) head[i]=0;
memset(root,0,sizeof(root));
}
return 0;
}