加强版求调!!!
  • 板块CF786B Legacy
  • 楼主husy
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/8/1 18:50
  • 上次更新2023/10/27 17:28:32
查看原帖
加强版求调!!!
484780
husy楼主2022/8/1 18:50
#include<bits/stdc++.h>
using namespace std;
const int N=6e5+10;
int head[8*N],ver[20*N],nex[20*N],edge[20*N],tot,d[8*N],v[8*N];
int n,m,s,root1,root2,cnt;
int len[8*N],que[8*N],que2[8*N],t1,t2;
int xx[8*N],ll[8*N],rr[8*N],zz[8*N],tt[8*N];
int nu[8*N];
long long num,ans;
priority_queue<pair<int ,int > >q;
const int mod=1e9+7;
void add(int x,int y,int z)
{
	ver[++tot]=y,edge[tot]=z,nex[tot]=head[x],head[x]=tot;
}
void dij(int str)
{
	memset(v,0,sizeof(v));
	d[nu[str]]=0;
	q.push(make_pair(0,nu[str]));
	while(q.size())
	{
		int x=q.top().second;q.pop();
		if(v[x])continue;
		v[x]=1;
		for(int i=head[x];i;i=nex[i])
		{
			int y=ver[i],z=edge[i];
			if(d[y]==-1||d[y]>d[x]+z)
			{
				d[y]=d[x]+z;
				q.push(make_pair(-d[y],y));
			}
		}
	}
	for(int i=1;i<=n;i++)
	if(d[nu[i]]!=-1)
	{
		ans+=1ll*d[nu[i]]*len[i]%mod;
		ans%=mod;
		num-=len[i];
	}
}
void build(int p,int l,int r)
{
	int addd=(l==r)?0:n*4;
	add(p+addd,n*4+(p>>1),0);
    if(l==r)
    {
    	nu[l]=p;
    	return ;
	}
	int mid=(l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	add(p,p*2,0);
	add(p,p*2+1,0);
} 
void treeadd(int p,int l1,int r1,int l2,int r2,int u,int z,int op)
{
	if(l2>r1||r2<l1)return ;
	if(l1<=l2&&r2<=r1)
	{
		if(op==2)add(nu[u],p,z);
		else 
		{
			int g=(l2==r2)?0:n*4;
			add(p+g,nu[u],z);
		}
		return ;
	}
	int mid=(l2+r2)>>1;
	if(l1<=mid)treeadd(p*2,l1,r1,l2,mid,u,z,op);
	if(r1>mid)treeadd(p*2+1,l1,r1,mid+1,r2,u,z,op);
}
int main()
{
	memset(d,-1,sizeof(d));
	scanf("%d%d%d",&n,&m,&s);
//	cnt=n;
//	build1(root1,1,n);
//	build2(root2,1,n);
	que[++t1]=s;
	num=n;
	for(int i=1;i<=m;i++)
	{
//		int type;
		scanf("%d",&tt[i]);
		if(tt[i]==1)
		{
//			int x,y,z;
			scanf("%d%d%d",&xx[i],&ll[i],&rr[i]);
			que[++t1]=xx[i];
			que[++t1]=ll[i];
		}
		else
		{
			scanf("%d%d%d%d",&xx[i],&ll[i],&rr[i],&zz[i]);
			que[++t1]=xx[i];
			que[++t1]=ll[i];
			que[++t1]=rr[i];
		}
	}
	sort(que+1,que+t1+1);
	for(int i=1;i<=t1;i++)if(i==1||que[i-1]!=que[i])que2[++t2]=que[i];
	t1=0;
	memset(que,0,sizeof(que));
	for(int i=1;i<=t2;i++){
		if(i>1&&que2[i]-que2[i-1]>1)
		{
			que[++t1]=que2[i-1]+1;
			len[t1]=que2[i]-que2[i-1]+1;
		}
		que[++t1]=que2[i],len[t1]=1;
	} 
	n=t1;
	s=lower_bound(que+1,que+t1+1,s)-que;
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
    	if(tt[i]==1)
    	{
    		int x=lower_bound(que+1,que+t1+1,xx[i])-que;
    		int y=lower_bound(que+1,que+t1+1,ll[i])-que;
    		add(nu[x],nu[y],rr[i]);
		}
		else
		{
			int x=lower_bound(que+1,que+1+n,xx[i])-que;
			int l=lower_bound(que+1,que+1+n,ll[i])-que;
			int r=lower_bound(que+1,que+1+n,rr[i])-que;
			int z=zz[i];
			treeadd(1,1,n,l,r,x,z,tt[i]);
		}
	}
	dij(s);
	printf("%lld %lld\n",ans,num);
	return 0;
}

n<=1000000000,m<=100000 样例没过,求调!!!

2022/8/1 18:50
加载中...