求助毒瘤题,莫名TLE
查看原帖
求助毒瘤题,莫名TLE
190926
Diwanul楼主2021/5/29 21:37

使用的是可持久化并查集,莫名其妙T飞为64分。

加了快读、O2也还是64分,不知道是人傻常数大还是复杂度假掉,但最容易出错的按秩合并经检查应该没有问题。

代码:

#include<bits/stdc++.h>

using namespace std;

const int N=200000,M=400000,Q=400000,LGN=20;
const int INF=0x3f3f3f3f;

int n,m,q,k,s;
int head[N+10],te;
int d[N+10];
bool lck[N+10];
int rt[M+10];

struct PST{
	#define mid ((l+r)>>1)
	int ls[M*LGN],rs[M*LGN],v[M*LGN],tn;
	int rt[M],trt;
	
	void Clear(){
		tn=trt=0;
	}
	
	void Build_d(int &u,const int &l,const int &r){
		u=tn++;
		if(l==r)v[u]=d[l];
		else Build_d(ls[u],l,mid),Build_d(rs[u],mid+1,r);
	}
	
	void Build(int &u,const int &l,const int &r,const int &x){
		u=tn++;
		if(l==r)v[u]=x;
		else Build(ls[u],l,mid,x),Build(rs[u],mid+1,r,x);
	}

	void Add(int &u,const int &old,const int &l,const int &r,const int &x,const int &y){
		u=tn++;
		if(l==r){
			v[u]=y;
			return;
		}
		ls[u]=ls[old],rs[u]=rs[old];
		if(x>mid)Add(rs[u],rs[old],mid+1,r,x,y);
		else Add(ls[u],ls[old],l,mid,x,y);
	}

	int Query(const int &u,const int &l,const int &r,const int &x){
		if(l==r)return v[u];
		if(x>mid)return Query(rs[u],mid+1,r,x);
		return Query(ls[u],l,mid,x);
	}
	#undef mid
};

struct PUFS{
	PST f,dep,ans;

	void Build(){
		f.Clear();
		dep.Clear();
		ans.Clear();
		f.Build(f.rt[f.trt++],1,n,-1);
		dep.Build(dep.rt[dep.trt++],1,n,1);
		ans.Build_d(ans.rt[ans.trt++],1,n);
	}

	int Find(const int &old,const int &x){
		int ls=f.Query(f.rt[old],1,n,x);
		return ~ls?Find(old,ls):x;
	}

	void Union(const int &old,int x,int y){
		x=Find(old,x),y=Find(old,y);
		int dx=dep.Query(dep.rt[old],1,n,x),dy=dep.Query(dep.rt[old],1,n,y),ax=ans.Query(ans.rt[old],1,n,x),ay=ans.Query(ans.rt[old],1,n,y);
		if(x!=y){
			if(dx>dy)swap(x,y),swap(dx,dy);
			f.Add(f.rt[f.trt++],f.rt[old],1,n,y,x);
			if(dx==dy)dep.Add(dep.rt[dep.trt++],dep.rt[old],1,n,x,dx+1);
			else dep.rt[dep.trt++]=dep.rt[old];
			ans.Add(ans.rt[ans.trt++],ans.rt[old],1,n,x,min(ax,ay));
		}
		else f.rt[f.trt++]=f.rt[old],dep.rt[dep.trt++]=dep.rt[old],ans.rt[ans.trt++]=ans.rt[old];
	}
	
	int Get(const int &old,int x){
		x=Find(old,x); 
		return ans.Query(ans.rt[old],1,n,x);
	}
}st;

struct edge{
	int v,nex,d,h;
}e[M*2+10];

struct edge_{
	int u,v,d,h;
	
	bool operator<(const edge_ &x)const{
		return h>x.h;
	}
}ee[M+10];

struct node{
	int id,d;

	bool operator<(const node &x)const{
		return d>x.d;
	}
};

void Adde(int u,int v,int d,int h){
	e[++te].nex=head[u];
	e[te].v=v;
	e[te].d=d;
	e[te].h=h;
	head[u]=te;
}

void Add(edge_ x){
	Adde(x.u,x.v,x.d,x.h);
	Adde(x.v,x.u,x.d,x.h);
}

node Node(int id,int d){
	node res;
	res.id=id;
	res.d=d;
	return res;
}

void Dij(){
	priority_queue<node> pq;
	d[1]=0;
	pq.push(Node(1,0));
	while(!pq.empty()){
		int u=pq.top().id;
		pq.pop();
		if(lck[u])continue;
		lck[u]=1;
		for(register int i=head[u];i;i=e[i].nex){
			int v=e[i].v,dis=e[i].d;
			if(!lck[v]&&d[v]>d[u]+dis){
				d[v]=d[u]+dis;
				pq.push(Node(v,d[v]));
			}
		}
	}
}

inline int read(){
	char c=getchar();
	int res=0,f=1;
	while(c>'9'||c<'0')f=(c=='-'?-1:f),c=getchar();
	while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
	return res*f;
}

int main(){
	int T=read();
	while(T--){
		memset(lck,0,sizeof lck);
		memset(d,0x3f,sizeof d);
		memset(head,0,sizeof head);
		te=0;
		n=read(),m=read();
		for(register int i=0;i<m;i++)
			ee[i].u=read(),ee[i].v=read(),ee[i].d=read(),ee[i].h=read(),Add(ee[i]);
		Dij();
		st.Build();
		sort(ee,ee+m);
		rt[0]=INF;
		for(register int i=0;i<m;i++)st.Union(i,ee[i].u,ee[i].v),rt[i+1]=ee[i].h;
		q=read(),k=read(),s=read();
		for(register int i=0,last=0;i<q;i++){
			int v=read(),p=read();
			v=(v+k*last-1)%n+1;
			p=(p+k*last)%(s+1);
			int l=0,r=m;
			while(l<r){
				int mid=(l+r+1)>>1;
				if(rt[mid]<=p)r=mid-1;
				else l=mid;
			}
			printf("%d\n",last=st.Get(l,v));
		}
	}
	return 0;
}
2021/5/29 21:37
加载中...