听说灌水区大佬多,求调P4768,玄关
  • 板块灌水区
  • 楼主LOvO
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/3/5 21:35
  • 上次更新2024/3/6 13:34:27
查看原帖
听说灌水区大佬多,求调P4768,玄关
533944
LOvO楼主2024/3/5 21:35

rt,代码如下 (做了5h只有5ptsQAQ。

#include<bits/stdc++.h>
using namespace std;
int n,m,qq,k,s,lasta;
struct N{
	int u,v,l,x;
}a[400005];
struct EDGE{
	int u,v;
	bool operator > (const EDGE aa) const {
		return v>aa.v;
	}
};
vector<EDGE> e[200005];
priority_queue<EDGE,vector<EDGE>,greater<EDGE> > q;
bool cmp1(N a,N b)
{
	return a.x<b.x;
}
struct NODE{
	int l,r,fa,val;
}d[200005<<5];
int root[200005],dist[200005],b[200005],mn[200005],cur,cnt;
bool vis[200005];
int build(int l,int r)
{
	int u=++cnt;
	if(l==r)
	{
		mn[u]=dist[d[u].fa=l];
		return u;
	}
	int mid=(l+r)>>1;
	d[u].l=build(l,mid);
	d[u].r=build(mid+1,r);
	return u;
}
int query(int rt,int l,int r,int x)
{
	if(l==r) return rt;
	int mid=(l+r)>>1;
	if(x<=mid) return query(d[rt].l,l,mid,x);
	return query(d[rt].r,mid+1,r,x);
}
int find(int id,int x)
{
	int u=query(root[id],1,n,x);
	if(d[u].fa==x) return u;
	return find(id,d[u].fa);
}
int uni(int id,int l,int r,int x,int fa)
{
	int u=++cnt;
	d[u]=d[id];
	if(l==r)
	{
		d[u].fa=fa;
		return u;
	}
	int mid=(l+r)>>1;
	if(x<=mid) d[u].l=uni(d[id].l,l,mid,x,fa);
	else d[u].r=uni(d[id].r,mid+1,r,x,fa);
	return u;
}
int str(int id,int l,int r,int x)
{
	int u=++cnt;
	d[u]=d[id];
	if(l==r)
	{
		d[u].val++;
		return u;
	}
	int mid=(l+r)>>1;
	if(x<=mid) d[u].l=str(d[id].l,l,mid,x);
	else d[u].r=str(d[id].r,mid+1,r,x);
	return u;
}
void merge(int id,int x,int y)//并查集合并节点
{
	int u=find(id,x),v=find(id,y);
	if(d[u].fa==d[v].fa) return ;
	if(d[u].val>d[v].val) swap(u,v);
	root[id]=uni(root[id-1],1,n,d[u].fa,d[v].fa);
	mn[root[id]]=min(mn[d[u].fa],mn[d[v].fa]);
	if(d[u].val==d[v].val) root[id]=str(root[id],1,n,d[v].fa);
}
int main()
{
//    freopen("return.in","r",stdin);
//    freopen("return.out","w",stdout);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		for(int i=1;i<=m;i++)
		{
			cin>>a[i].u>>a[i].v>>a[i].l>>a[i].x;
			e[a[i].u].push_back({a[i].v,a[i].l});
			e[a[i].v].push_back({a[i].u,a[i].l});
		}
		memset(dist,0x3f,sizeof(dist));
		memset(vis,0,sizeof(vis));
      		//最短路(关于SPFA,他死了。
		q.push({1,0}),dist[1]=0;
		while(!q.empty())
		{
			EDGE cur=q.top();
			q.pop();
			if(vis[cur.u]) continue;
			vis[cur.u]=true;
			for(int i=0;i<e[cur.u].size();i++)
				if(dist[e[cur.u][i].u]>dist[cur.u]+e[cur.u][i].v)
				{
					dist[e[cur.u][i].u]=dist[cur.u]+e[cur.u][i].v;
					q.push({e[cur.u][i].u,dist[cur.u]+e[cur.u][i].v});
				}
		}
		
		sort(a+1,a+1+m,cmp1);
		cin>>qq>>k>>s;
		b[m+1]=s+1;
		for(int i=1;i<=m;i++) b[i]=a[i].x;
		int p=unique(b+1,b+2+m)-b-1;//离散化
		root[p]=build(1,n);
		int j=m;
		for(int i=p-1;i>=1;i--)
		{
			root[i]=root[i-1];
			for(;j>=1&&a[j].x==b[i];j--)
				merge(i,a[j].u,a[j].v);
		}
//		for(int i=1;i<=n;i++) cout<<root[i]<<" ";
//		cout<<endl<<endl;
//		for(int i=1;i<=m;i++) cout<<a[i].u<<" "<<a[i].v<<" "<<a[i].l<<" "<<a[i].x<<endl;
//		cout<<endl;
//		for(int i=1;i<=40;i++)
//			cout<<i<<" "<<d[i].l<<"\n"<<i<<" "<<d[i].r<<" "<<d[i].fa<<" "<<d[i].val<<endl;
		while(qq--)
		{
			int u,v;
			cin>>u>>v;
			u=(u+k*lasta)%(s+1),v=(v+k*lasta-1)%n+1;
			cout<<(lasta=mn[find(root[upper_bound(b+1,b+p+1,u)-b],v)])<<endl;
		}
		memset(mn,0,sizeof(mn));
		memset(a,0,sizeof(a));
		memset(d,0,sizeof(d));
		memset(root,0,sizeof(root));
		cur=0,cnt=0,lasta=0;
		while(!q.empty()) q.pop();
	}
	return 0;
}
2024/3/5 21:35
加载中...