#spfa# [牛客集训] 牛表

main points

牛表


Solution

结论大概是打表发现 a n s ans ans矩阵中在 2000 2000 2000以内最大的数是 17 17 17
然后对于每一个数前后17个数相乘连边求最短路。
注意一下有两个不同的模数,然后不同的循环注意i和j不要搞混。


Code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std; 
const int mod=998244353; 
const int N=3050; 

int P,t; 
struct node{
	int y,z,next; 
}a[N*45];
int tot; 
bool b[N]; 
int dis[N],head[N]; 
queue<int> q; 

void add(int x,int y,int z){
	a[++tot]=(node){y,z,head[x]}, head[x]=tot; 
}

int ksm(int x,int y){
	int ans=1; 
	for(;y;y>>=1,x=1ll*x*x%mod)
		if (y&1) ans=1ll*ans*x%mod; 
	return ans; 
}

void spfa(int g){
	memset(b,0,sizeof(b)); 
	memset(dis,0x3f,sizeof(dis)); 
	
	q.push(g); dis[g]=0; b[g]=1; 
	
	while (q.size()){
		int x=q.front(); q.pop(); 
		for(int i=head[x];i;i=a[i].next){
			int y=a[i].y; 
			if (dis[y]>dis[x]+a[i].z){
				dis[y]=dis[x]+a[i].z; 
				if (!b[y]) q.push(y),b[y]=1; 
			}
		}
		b[x]=0; 
	}
	
}

int main(){
	
	scanf("%d%d",&P,&t); 
	
	for(int i=1;i<P;i++)
		for(int j=max(i-17,1);j<=i;j++)
		add(i,i*j%P,i-j); 
	for(int i=1;i<P;i++)
		for(int j=i+1;j<=min(P-1,i+17);j++) 
		add(i,i*j%P,j-i); 
		
	int ans=0; 
	for(int i=1;i<P;i++){
		spfa(i); 
		int k=ksm(t,(i-1)*(P-1))%mod; 
		
		for(int j=1;j<P;j++)
			ans=(ans+1ll*dis[j]*k%mod)%mod,k=1ll*k*t%mod; 
	}
		
	printf("%d",ans); 
		
	return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值