rt,代码如下 (做了5h只有5ptsQAQ。
#include<bits/stdc++.h>
using namespace std;
int n,m,qq,k,s,lasta;
struct N{
int u,v,l,x;
}a[400005];
struct EDGE{
int u,v;
bool operator > (const EDGE aa) const {
return v>aa.v;
}
};
vector<EDGE> e[200005];
priority_queue<EDGE,vector<EDGE>,greater<EDGE> > q;
bool cmp1(N a,N b)
{
return a.x<b.x;
}
struct NODE{
int l,r,fa,val;
}d[200005<<5];
int root[200005],dist[200005],b[200005],mn[200005],cur,cnt;
bool vis[200005];
int build(int l,int r)
{
int u=++cnt;
if(l==r)
{
mn[u]=dist[d[u].fa=l];
return u;
}
int mid=(l+r)>>1;
d[u].l=build(l,mid);
d[u].r=build(mid+1,r);
return u;
}
int query(int rt,int l,int r,int x)
{
if(l==r) return rt;
int mid=(l+r)>>1;
if(x<=mid) return query(d[rt].l,l,mid,x);
return query(d[rt].r,mid+1,r,x);
}
int find(int id,int x)
{
int u=query(root[id],1,n,x);
if(d[u].fa==x) return u;
return find(id,d[u].fa);
}
int uni(int id,int l,int r,int x,int fa)
{
int u=++cnt;
d[u]=d[id];
if(l==r)
{
d[u].fa=fa;
return u;
}
int mid=(l+r)>>1;
if(x<=mid) d[u].l=uni(d[id].l,l,mid,x,fa);
else d[u].r=uni(d[id].r,mid+1,r,x,fa);
return u;
}
int str(int id,int l,int r,int x)
{
int u=++cnt;
d[u]=d[id];
if(l==r)
{
d[u].val++;
return u;
}
int mid=(l+r)>>1;
if(x<=mid) d[u].l=str(d[id].l,l,mid,x);
else d[u].r=str(d[id].r,mid+1,r,x);
return u;
}
void merge(int id,int x,int y)//并查集合并节点
{
int u=find(id,x),v=find(id,y);
if(d[u].fa==d[v].fa) return ;
if(d[u].val>d[v].val) swap(u,v);
root[id]=uni(root[id-1],1,n,d[u].fa,d[v].fa);
mn[root[id]]=min(mn[d[u].fa],mn[d[v].fa]);
if(d[u].val==d[v].val) root[id]=str(root[id],1,n,d[v].fa);
}
int main()
{
// freopen("return.in","r",stdin);
// freopen("return.out","w",stdout);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>a[i].u>>a[i].v>>a[i].l>>a[i].x;
e[a[i].u].push_back({a[i].v,a[i].l});
e[a[i].v].push_back({a[i].u,a[i].l});
}
memset(dist,0x3f,sizeof(dist));
memset(vis,0,sizeof(vis));
//最短路(关于SPFA,他死了。
q.push({1,0}),dist[1]=0;
while(!q.empty())
{
EDGE cur=q.top();
q.pop();
if(vis[cur.u]) continue;
vis[cur.u]=true;
for(int i=0;i<e[cur.u].size();i++)
if(dist[e[cur.u][i].u]>dist[cur.u]+e[cur.u][i].v)
{
dist[e[cur.u][i].u]=dist[cur.u]+e[cur.u][i].v;
q.push({e[cur.u][i].u,dist[cur.u]+e[cur.u][i].v});
}
}
sort(a+1,a+1+m,cmp1);
cin>>qq>>k>>s;
b[m+1]=s+1;
for(int i=1;i<=m;i++) b[i]=a[i].x;
int p=unique(b+1,b+2+m)-b-1;//离散化
root[p]=build(1,n);
int j=m;
for(int i=p-1;i>=1;i--)
{
root[i]=root[i-1];
for(;j>=1&&a[j].x==b[i];j--)
merge(i,a[j].u,a[j].v);
}
// for(int i=1;i<=n;i++) cout<<root[i]<<" ";
// cout<<endl<<endl;
// for(int i=1;i<=m;i++) cout<<a[i].u<<" "<<a[i].v<<" "<<a[i].l<<" "<<a[i].x<<endl;
// cout<<endl;
// for(int i=1;i<=40;i++)
// cout<<i<<" "<<d[i].l<<"\n"<<i<<" "<<d[i].r<<" "<<d[i].fa<<" "<<d[i].val<<endl;
while(qq--)
{
int u,v;
cin>>u>>v;
u=(u+k*lasta)%(s+1),v=(v+k*lasta-1)%n+1;
cout<<(lasta=mn[find(root[upper_bound(b+1,b+p+1,u)-b],v)])<<endl;
}
memset(mn,0,sizeof(mn));
memset(a,0,sizeof(a));
memset(d,0,sizeof(d));
memset(root,0,sizeof(root));
cur=0,cnt=0,lasta=0;
while(!q.empty()) q.pop();
}
return 0;
}