为啥我T飞了
查看原帖
为啥我T飞了
530468
_determination_楼主2024/7/24 15:47

交了一发60分,目测复杂度 O(nlog⁡2n)O(n\log^2n)。一个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;
}
2024/7/24 15:47
加载中...