持久并查集.如何实现连通块内最小
查看原帖
持久并查集.如何实现连通块内最小
1057821
sad_lin楼主2024/9/26 15:37

RT

调了一上午,本来写了个可持久并查集模板很开心,想到归程这题也是可持久并查集,就想试一试,发现写半天就顶不住了,看题解也没有码风一样的,所以求求大佬帮助,口胡一下或者改改我的代码也行,目前是WA了,MLE、TLE、RE先不管了。

谢谢大佬们。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int M=4e5+10;
const int N=4e5+10;
const int MAX=1e7;
int n,m;

struct node{
	int next,u,v,h,s;
}e[M];
int head[M];
int cc=1;

void addd(int u,int v,int s,int h){//加边 
	e[cc].v=v;
	e[cc].u=u;
	e[cc].s=s;
	e[cc].h=h;
	e[cc].next=head[u];
	head[u]=cc++;
}
bool cmp(node g,node h){
	return g.h>h.h;
}

struct ss{
	int fa,h,ls,rs;
	ll d;
}a[MAX];
int ti[MAX];
int cnt=0;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

ll dis[N];
int vis[N]; 
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
void dijkstra(){
	dis[1]=0;
	q.push(make_pair(0,1));	
	while(!q.empty()){
		pair<int,int> osa=q.top();
		q.pop();
		int id=osa.second;
		if(vis[id]==1) continue;
		vis[id]=1;
		for(int i=head[id];~i;i=e[i].next){
			int y=e[i].v;
 			if(vis[y]==1) continue;
			if(dis[y]>dis[id]+e[i].s){
				dis[y]=dis[id]+e[i].s;
				q.push(make_pair(dis[y],y));
			}
		}
	}
}
 
int ad(int x){
	a[++cnt]=a[x];
	return cnt;
}
int build(int l,int r){
	int to=++cnt;
	if(l==r){
		a[to].fa=l;
		a[to].d=dis[l];
		return to;
	}
	int mid=(l+r)>>1;
	a[to].ls=build(l,mid);
	a[to].rs=build(mid+1,r);
	return to;
}
int ff(int now,int l,int r,int x){
	if(l==r) return now;
	int mid=(l+r)>>1;
	if(mid>=x) return ff(a[now].ls,l,mid,x);	
	else return ff(a[now].rs,mid+1,r,x);
}
int find(int now,int x){
	int fa=ff(ti[now],1,n,x);
	if(a[fa].fa==x){
		return fa;
	}
	int result=find(now,a[fa].fa);
	a[fa].fa=a[result].fa;
	return result;
}
int o;
int hb(int now,int l,int r,int x,int f){
	int to=ad(now);
	if(l==r){
		a[to].fa=f;
		o=to;
		return to;
	}
	int mid=(l+r)>>1;
	if(mid>=x){
		a[to].ls=hb(a[now].ls,l,mid,x,f);
	}
	else{
		a[to].rs=hb(a[now].rs,mid+1,r,x,f);
	}
	return to;
}

int add(int now,int l,int r,int x){
	int to=ad(now);
	if(l==r){
		a[to].h++;
		a[to].d=min(a[to].d,a[o].d);
		return to;
	}
	int mid=(l+r)>>1;
	if(mid>=x)
		a[to].ls=add(a[now].ls,l,mid,x);
	else
		a[to].rs=add(a[now].rs,mid+1,r,x);
	return to;
}
void merge(int now,int x,int y){
	x=find(now,x),y=find(now,y);
	if(a[x].fa!=a[y].fa){
		if(a[x].h>a[y].h)
			swap(x,y);
		o=0;
		ti[now]=hb(ti[now-1],1,n,a[x].fa,a[y].fa);
//		if(a[x].h==a[y].h)
			ti[now]=add(ti[now],1,n,a[y].fa);
	}
}

void rest(){
	cc=1;
	cnt=0;
	memset(head,-1,sizeof head);
	memset(e,0,sizeof e);
	memset(a,0,sizeof a);
	memset(dis,0x3f,sizeof dis);
	memset(vis,0,sizeof vis);
	memset(ti,0,sizeof ti);
}

int search(int x){
	int l=1,r=cc,mid,res=0;
	while(l<=r){
		mid=(l+r)>>1;
		if(e[mid].h>x){
			res=mid,l=mid+1;
		}
		else{
			r=mid-1;
		}
	}
	return res;
}

void solve(){
	n=read(),m=read();
	
	for(int i=1;i<=m;i++){
		int u,v,s,h;
		u=read(),v=read(),s=read(),h=read();
		addd(u,v,s,h);
		addd(v,u,s,h);
	}
	dijkstra();
	cc--;
	sort(e+1,e+cc+1,cmp);
	
	ti[0]=build(1,n);
	
	for(int i=1;i<=cc;i++){
		ti[i]=ti[i-1];
		merge(i,e[i].u,e[i].v);
	}
	
	int q,k,s,lastans=0,ans;
	q=read(),k=read(),s=read();
	while(q--){
		int v,p;
		v=read(),p=read();	
		v=(v+k*lastans-1)%n+1;
		p=(p+k*lastans)%(s+1);
		int pos=search(p);
		int loc=find(pos,v);
		ans=a[loc].d;
		lastans=ans;
		cout<<ans<<"\n";
	}
} 

signed main(){
    ios::sync_with_stdio(false);
//    freopen("return7.in","r",stdin);
//    freopen("return.out","w",stdout);
    int t;
    t=read();
    while(t--){
		rest();
    	solve();
	}
    return 0;
}
2024/9/26 15:37
加载中...