求助线段树优化建图
查看原帖
求助线段树优化建图
376348
赛克尔だよ楼主2023/11/16 10:07

RT,调了一上午了,就10分

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,p,t;
int a,b,c,d;
struct edge{
	int to,w,next;
}e[20000007];
int cnt,head[20000007];
void insert(int u,int v,int w){
	e[++cnt].to=v;
	e[cnt].w=w;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int node[20000007];
int ns[20000007],sn[20000007],cnt1,cnt2;
int pp[20000007];
int value[20000005],S;
int nb[20000005];
void testing(int x,int l,int r){
	++t;
	if(l==r)return;
	int mid=l+r>>1;
	testing(x<<1,l,mid);
	testing(x<<1|1,mid+1,r);
	return;
}
void start(int x,int l,int r){
//	value[x]=value[x+t]=10000000;
	if(l==r){
		pp[x]=pp[x+t]=l;
		if(l==p){
//			value[x]=value[x+t]=0;
			S=x;
		}
		return;
	}
	int mid=l+r>>1;
	insert(x,x<<1,0);
	insert(x,x<<1|1,0);
	insert(x<<1,x+t,0);
	insert(x<<1|1,x+t,0);
	start(x<<1,l,mid);
	start(x<<1|1,mid+1,r);
	return;
}
int sbb=0,sabi=0;
void Dijkstra() {
	memset(value,0x3f,sizeof(value));
	deque<int> q;
	value[S]=0;
	q.push_back(S);
	while(!q.empty()) {
		int now=q.front();
		q.pop_front();
		for(int i=head[now]; i; i=e[i].next) {
			int y=e[i].to,v=e[i].w;
			if(value[y]>value[now]+v) {
				value[y]=value[now]+v;
				if(v)q.push_back(y);
				else q.push_front(y);
			}
		}
	}
}
void find1(int x,int L,int R,int l,int r){
	if(l<=L&&R<=r){
		ns[++cnt1]=x;
		return;
	}
	int mid=L+R>>1;
	if(l<=mid)find1(x<<1,L,mid,l,r);
	if(r>mid)find1(x<<1|1,mid+1,R,l,r);
	return;
}
void find2(int x,int L,int R,int l,int r){
	if(l<=L&&R<=r){
		sn[++cnt2]=x;
		return;
	}
	int mid=L+R>>1;
	if(l<=mid)find2(x<<1,L,mid,l,r);
	if(r>mid)find2(x<<1|1,mid+1,R,l,r);
	return;
}
void out(int x,int l,int r){
	if(l==r){
		printf("%lld\n",value[x]);
		return;
	}
	int mid=l+r>>1;
	out(x<<1,l,mid);
	out(x<<1|1,mid+1,r);
	return;
}
main(){
	scanf("%lld%lld%lld",&n,&m,&p);
	testing(1,1,n);
	start(1,1,n);
	//printf("%d ",t);
	for(int i=1;i<=m;i++){
		scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
		cnt1=cnt2=0;
		find1(1,1,n,a,b);
		find2(1,1,n,c,d);
		for(int i=1;i<=cnt1;i++)
			for(int j=1;j<=cnt2;j++){
				insert(ns[i],sn[j],1);
				insert(sn[j],ns[i],1);
				insert(ns[i],sn[j]+t,1);
				insert(sn[j],ns[i]+t,1);
				insert(ns[i]+t,sn[j],1);
				insert(sn[j]+t,ns[i],1);
				insert(ns[i]+t,sn[j]+t,1);
				insert(sn[j]+t,ns[i]+t,1);
			}
	}
	Dijkstra();
	out(1,1,n);
//	printf("%d",value[3]);
}
2023/11/16 10:07
加载中...