交了一发60分,目测复杂度 O(nlog2n)。一个log是按秩合并,一个是可持久化。但是大样例5跑出来34s,求大佬看看我哪里写的丑了或者哪里假了导致复杂度退化
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int mod=1e9+7,inf=0x3f3f3f3f3f3f3f3f;
int n,m;
vector<pair<int,int> >e[200010];
struct E{
int u,v,l,a;
}edge[400010];
int cmp(E p,E q){return p.a>q.a;}
int dis[200010],vis[200010];
struct node{
int x,v;
bool operator <(const node &y)const{
return v>y.v;
}
};
priority_queue<node>q;
void dij()
{
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[1]=0;
q.push({1,0});
while(!q.empty())
{
int x=q.top().x;
q.pop();
if(vis[x])continue;
vis[x]=1;
for ( int i = 0 ; i < e[x].size() ; i++ )
{
int v=e[x][i].first,w=e[x][i].second;
if(dis[v]>dis[x]+w)
{
dis[v]=dis[x]+w;
q.push({v,dis[v]});
}
}
}
}
vector<pair<int,int> >fa[200010],mn[200010],siz[200010];//ver,val
int finf(int x,int ver)
{
int l=0,r=fa[x].size()-1;
while(l<r)
{
int mid=(l+r+1)/2;
if(fa[x][mid].first<=ver)l=mid;
else r=mid-1;
}
return l;
}
int finm(int x,int ver)
{
int l=0,r=mn[x].size()-1;
while(l<r)
{
int mid=(l+r+1)/2;
if(mn[x][mid].first<=ver)l=mid;
else r=mid-1;
}
return l;
}
int find(int x,int ver)
{
int v=finf(x,ver);
if(fa[x][v].second==x)return x;
return find(fa[x][v].second,ver);
}
void merge(int u,int v,int ver)
{
u=find(u,ver);
v=find(v,ver);
int x=siz[v][siz[v].size()-1].second,y=siz[u][siz[u].size()-1].second;
if(x<y)swap(u,v);
siz[v].push_back({ver,x+y});
x=mn[v][mn[v].size()-1].second,y=mn[u][mn[u].size()-1].second;
mn[v].push_back({ver,min(x,y)});
fa[u].push_back({ver,v});
}
void solve()
{
cin >> n >> m;
for ( int i = 1 ; i <= n ; i++ )fa[i].clear(),mn[i].clear(),siz[i].clear(),e[i].clear();
for ( int i = 1 ; i <= m ; i++ )
{
cin >> edge[i].u >> edge[i].v >> edge[i].l>> edge[i].a;
e[edge[i].u].push_back({edge[i].v,edge[i].l});
e[edge[i].v].push_back({edge[i].u,edge[i].l});
}
dij();
// for ( int i = 1 ; i <= n ; i++ )cout << dis[i] << " ";
// cout << endl;
sort(edge+1,edge+1+m,cmp);
for ( int i = 1 ; i <= n ; i++ )fa[i].push_back({0,i}),mn[i].push_back({0,dis[i]}),siz[i].push_back({0,1});
for ( int i = 1 ; i <= m ; i++ )
{
merge(edge[i].u,edge[i].v,i);
// for ( int j = 1 ; j <= n ; j++ )
// {
// cout << mn[j][finm(j,i)].second << " ";
//// cout << find(j,i) << " ";
//// cout << fa[j][fin(j,i)].second << " ";
// }
// cout << endl;
}
int lstans=0,q,k,s;
cin >> q >> k >> s;
while(q--)
{
int v,p;
cin >> v >> p;
v=(v+k*lstans-1)%n+1;
p=(p+k*lstans)%(s+1);
int l=1,r=m;
if(edge[1].a>p)
{
while(l<r)
{
int mid=(l+r+1)/2;
if(edge[mid].a>p)l=mid;
else r=mid-1;
}
}else l=0;
// for ( int i = 1 ; i <= l ; i++ )cout << edge[i].u << " " << edge[i].v << endl;
v=find(v,l);
// cout << endl;
lstans=mn[v][finm(v,l)].second;
cout << lstans << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
// freopen("return5.in","r",stdin);
// freopen("return.out","w",stdout);
int T;
cin >> T;
while(T--)solve();
return 0;
}