T飞了,帮帮看看有什么优化办法(自认为复杂度是O(nlogn)的)
查看原帖
T飞了,帮帮看看有什么优化办法(自认为复杂度是O(nlogn)的)
556740
hzx360楼主2023/8/12 12:59

可持久化并查集做法

#include<bits/stdc++.h>
using namespace std;
const int N=8e5+100,M=3e6+100;
const int inf=2e9+100;
#define re register
int n,m,Q,K,S,dis[N];
int head[N],to[N],w[N],ne[N],tot;
void add(int x,int y,int z){
	ne[++tot]=head[x];
	to[tot]=y,w[tot]=z;
	head[x]=tot;
}
bool vis[N];
struct node{
	int id,dis;
	bool operator <(node it)const{
		return dis>it.dis;
	}
};priority_queue<node>q;
struct edge{int u,v,l,a;}e[N];
bool cmp(edge A,edge B){return A.a>B.a;}
void dij(){
	dis[1]=0;
	q.push((node){1,0});
	while(!q.empty()){
		node u=q.top();q.pop();
		if(vis[u.id]) continue;
		vis[u.id]=1;
		for(re int i=head[u.id];i;i=ne[i]){
			int v=to[i];
			if(dis[v]>u.dis+w[i]){
				dis[v]=u.dis+w[i];
				q.push((node){v,dis[v]});
			}
		}
	}
}
int cnt,rtf[N],rtde[N],rti[N];
struct tree{int l,r,val;}t[M]; 
inline void build(int &i,int l,int r){
	i=++cnt;
	if(l==r) return void(t[i].val=l);
	int mid=(l+r)>>1;
	build(t[i].l,l,mid),build(t[i].r,mid+1,r);
}
inline void build_mi(int &i,int l,int r){
	i=++cnt;
	if(l==r) return void(t[i].val=dis[l]);
	int mid=(l+r)>>1;
	build_mi(t[i].l,l,mid),build_mi(t[i].r,mid+1,r);
}
inline void build_de(int &i,int l,int r){
	i=++cnt;
	if(l==r) return void(t[i].val=0);
	int mid=(l+r)>>1;
	build_de(t[i].l,l,mid),build_de(t[i].r,mid+1,r);
}
inline void update(int &i,int j,int l,int r,int pos,int val){
	i=++cnt;
	t[i]=t[j];
	if(l==r) return void(t[i].val=val);
	int mid=(l+r)>>1;
	if(pos<=mid) update(t[i].l,t[j].l,l,mid,pos,val);
	else update(t[i].r,t[j].r,mid+1,r,pos,val);
}
inline int query(int i,int l,int r,int pos){
	if(l==r) return t[i].val;
	int mid=(l+r)>>1;
	if(pos<=mid) return query(t[i].l,l,mid,pos);
	else return query(t[i].r,mid+1,r,pos);
}
inline int find(int i,int x){
	int fx=query(rtf[i],1,n,x);
	return fx==x?x:find(i,fx);	
}
inline void merge(int i,int x,int y){
	x=find(i-1,x),y=find(i-1,y);
	if(x==y) rtf[i]=rtf[i-1],rtde[i]=rtde[i-1],rti[i]=rti[i-1];
	else{
		int mix=query(rti[i-1],1,n,x),miy=query(rti[i-1],1,n,y);
		int dex=query(rtde[i-1],1,n,x),dey=query(rtde[i-1],1,n,y);
		if(dex<dey){
			update(rtf[i],rtf[i-1],1,n,x,y),rtde[i]=rtde[i-1];
			if(mix<miy) update(rti[i],rti[i-1],1,n,y,mix);
			else rti[i]=rti[i-1];
		}
		else if(dex>dey){
			update(rtf[i],rtf[i-1],1,n,y,x),rtde[i]=rtde[i-1];
			if(miy<mix) update(rti[i],rti[i-1],1,n,x,miy);
			else rti[i]=rti[i-1];
		}
		else{
			update(rtf[i],rtf[i-1],1,n,x,y),update(rtde[i],rtde[i-1],1,n,y,dey+1);
			if(mix<miy) update(rti[i],rti[i-1],1,n,y,mix);
			else rti[i]=rti[i-1];	
		}
	}
}
void deal(){
	for(re int i=1;i<=n;i++) head[i]=vis[i]=0,dis[i]=inf;
	cnt=tot=0;
}
void work(){
	cin>>n>>m;	
	deal();
	for(int i=1;i<=m;i++) scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].l,&e[i].a),add(e[i].u,e[i].v,e[i].l),add(e[i].v,e[i].u,e[i].l);
	cin>>Q>>K>>S;
	dij();
	build(rtf[0],1,n),build_mi(rti[0],1,n),build_de(rtde[0],1,n);
	sort(e+1,e+1+m,cmp);
	for(int i=1;i<=m;i++) merge(i,e[i].u,e[i].v);
	int last_ans=0;
	while(Q--){
		int v0,p0;
		scanf("%d%d",&v0,&p0);
		int v=(v0+K*last_ans-1)%n+1;
		int p=(p0+K*last_ans)%(S+1);
		int l=1,r=m,pos=0;
		while(l<=r){
			int mid=(l+r)>>1;
			if(e[mid].a>p) l=mid+1,pos=mid;
			else r=mid-1;
		}
		last_ans=query(rti[pos],1,n,find(pos,v));
		cout<<last_ans<<endl;
	}
}
signed main(){
	int T;cin>>T;
	while(T--) work();
}
2023/8/12 12:59
加载中...