求助可持久化并查集写法 12pts
查看原帖
求助可持久化并查集写法 12pts
93701
Morgen_Kornblume楼主2021/9/30 23:04

只过了前两个点,第三个点第一组数据过了,第二组数据过不去,很灵异……

跪求大佬帮助

#include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> pii;


const int maxn=200010,maxm=400010;
int n,m;
int T;
struct edge{
	int u,v,a;//a->altitude
};
edge ed[maxm];

bool mmp(edge tp1,edge tp2){
	return tp1.a>tp2.a;
}

struct graphics{
	vector<pii>to[maxn];
	int dist[maxn];
	int vis[maxn];
	
	void inital(){
		for(int i=1;i<maxn;i++){
			to[i].clear();
		}
	}
	
	void add(int u,int v,int l){
		to[u].push_back(make_pair(v,l));
		to[v].push_back(make_pair(u,l));
	}
	
	void djs(){
		memset(dist,0x3f,sizeof(dist));
		memset(vis,0,sizeof(vis));
		dist[1]=0;
		priority_queue<pii,vector<pii>,greater<pii>>q;
		q.push(make_pair(0,1));
		
		while(!q.empty()){
			int nowa=q.top().second;q.pop();
			if(vis[nowa])continue;
			vis[nowa]=1;
			
			for(pii tmp:to[nowa]){
				int go=tmp.first,len=tmp.second;
				if(dist[go]>dist[nowa]+len){
					dist[go]=dist[nowa]+len;
					if(!vis[go])q.push(make_pair(dist[go],go));
				}
			}
		}
		
//		for(int i=1;i<=n;i++){
//			cout<<dist[i]<<" ";
//		}cout<<endl;
//		system("pause");
	}
}g[4];

struct point{
	int ls,rs,val;
};

int rt[maxm];
struct persistance_segement_tree{
	
	vector<point>dat;
	
	void init(){
		dat.clear();
	}
	
	void build(int nowa,int l,int r,int mode){
		if(l==r){
			if(mode==1)dat[nowa].val=l;//fa
			else if(mode==2)dat[nowa].val=1;//zhi
			else dat[nowa].val=g[T].dist[l];//minn
			return;
		}
		int mid=(l+r)>>1;
		dat[nowa].ls=dat.size();
		dat.push_back((point){0,0,0});
		build(dat[nowa].ls,l,mid,mode);
		dat[nowa].rs=dat.size();
		dat.push_back((point){0,0,0});
		build(dat[nowa].rs,mid+1,r,mode);
	}
	
	void modify(int bs,int nowa,int l,int r,int tar,int nval){
		if(l==r){
			dat[nowa].val=nval;
			return;
		}
		int mid=(l+r)>>1;
		if(tar<=mid){
			dat[nowa].ls=dat.size();
			dat.push_back((point){0,0,0});
			dat[nowa].rs=dat[bs].rs;
			modify(dat[bs].ls,dat[nowa].ls,l,mid,tar,nval);
		}
		else{
			dat[nowa].rs=dat.size();
			dat.push_back((point){0,0,0});
			dat[nowa].ls=dat[bs].ls;
			modify(dat[bs].rs,dat[nowa].rs,mid+1,r,tar,nval);
		}
	} 
	
	int query(int nowa,int l,int r,int tar){
		if(l==r)return dat[nowa].val;
		int mid=(l+r)>>1;
		if(tar<=mid)return query(dat[nowa].ls,l,mid,tar);
		else return query(dat[nowa].rs,mid+1,r,tar);
	}
	
}fa[4],zhi[4],minn[4];

int getfa(int x,int ver){
	int fax=fa[T].query(rt[ver],1,n,x);
	return x==fax?x:getfa(fax,ver);
}



int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	cin>>T;
	
	while(T--){
		//initialize arrays
		memset(ed,0,sizeof(ed));
		fa[T].init();
		zhi[T].init();
		minn[T].init();
		g[T].inital();
		memset(rt,0,sizeof(rt));
		///////////////////
		
		cin>>n>>m;
		
		int u,v,l,a;
		for(int i=1;i<=m;i++){
			cin>>u>>v>>l>>a;
			ed[i]=((edge){u,v,a});
			g[T].add(u,v,l);
		}
		
		sort(ed+1,ed+1+m,mmp);
		
		g[T].djs();
		
		/////////////////////////////
		//build the union_find_set
		rt[0]=0;
		fa[T].dat.push_back((point){0,0,0});
		zhi[T].dat.push_back((point){0,0,0});
		minn[T].dat.push_back((point){0,0,0});
		fa[T].build(0,1,n,1);
		zhi[T].build(0,1,n,2);
		minn[T].build(0,1,n,3);
		
		for(int i=1;i<=m;i++){
			int pos=i-1;
			
//			cout<<ed[pos].u<<" "<<ed[pos].v<<" "<<ed[pos].a<<endl;
			
			int fx=getfa(ed[i].u,pos),fy=getfa(ed[i].v,pos);
//			cout<<fx<<" "<<fy<<endl;
//			system("pause");
			if(fx==fy){
				rt[i]=rt[pos];
				continue;
			}
			int zfx=zhi[T].query(rt[pos],1,n,fx),zfy=zhi[T].query(rt[pos],1,n,fy);
//			cout<<zfx<<" "<<zfy<<endl;
//			system("pause");
			int mfx=minn[T].query(rt[pos],1,n,fx),mfy=minn[T].query(rt[pos],1,n,fy);
//			cout<<mfx<<" "<<mfy<<endl;
//			system("pause");
			if(zfx<zfy)swap(fx,fy),swap(zfx,zfy);
			rt[i]=fa[T].dat.size();
			fa[T].dat.push_back((point){0,0,0});
			zhi[T].dat.push_back((point){0,0,0});
			minn[T].dat.push_back((point){0,0,0});
			fa[T].modify(rt[pos],rt[i],1,n,fy,fx);
			if(zfx==zfy)zfx++;
			zhi[T].modify(rt[pos],rt[i],1,n,fx,zfx);
			minn[T].modify(rt[pos],rt[i],1,n,fx,min(mfx,mfy));
		}
		/////////////////////////////
		
		int q,k,s;int lastans=0;
		cin>>q>>k>>s;
		
		int st,wa;//start point und water altitude
		for(int i=1;i<=q;i++){
			cin>>st>>wa;
			st=((st+k*lastans-1)%n)+1;
			wa=(wa+k*lastans)%(s+1);
			//cout<<wa<<endl;
			
			//binary search to find the exact state
			//query minn to get the answer;
			
			int l=1,r=m;
			int exa=0;
			while(l<=r){
				//cout<<l<<" "<<r<<endl;
				int mid=(l+r)>>1;
				//cout<<mid<<endl;
				//cout<<ed[mid].a<<" "<<wa<<endl;
				if(ed[mid].a>wa)exa=mid,l=mid+1;
				else r=mid-1;
				//cout<<exa<<endl;
				//system("pause");
			}
			
			//cout<<exa<<endl;
			int fast=getfa(st,exa);
			//cout<<fast<<endl;
			//system("pause");
			lastans=minn[T].query(rt[exa],1,n,fast);
			cout<<lastans<<endl;
		}
	}
	
	return 0;
}
2021/9/30 23:04
加载中...