Description
给出一张有向图(
n≤400
n
≤
400
),每条边有随时间T变化的边权,公式为:
si∗|T−pi|+ci (si,ci,pi给出)
s
i
∗
|
T
−
p
i
|
+
c
i
(
s
i
,
c
i
,
p
i
给
出
)
多组询问(
≤2e6
≤
2
e
6
),问给出时间和起点,随机游走到终点n的期望距离,(走的时候不需要消耗时间)
Solution
显然的,我们只需要记录每个点期望经过次数,即可算出总的期望经过距离,
我们可以通过高斯消元解决图上定起点随机游走问题,具体的:
ki,j k i , j 为j走到i的概率, ci c i 当i为起点是为1,其他为0,
但对于这种不定起点的,可以这么解决:
先把方程与
x
x
有关项移到左边,另一边为常数,
那么,这个方程就变成了矩阵X,K,C之间的关系:
移项:
于是求出K的逆矩阵,即可快速求出不同起点时,每个点的期望经过次数,
关于本题绝对值的处理方法,离线排序即可。
复杂度: O(n3+nm) O ( n 3 + n m )
Code
#include <cstdio>
#include <algorithm>
#include <iostream>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define efo(i,q) for(int i=A[q];i;i=B[i][0])
#define min(q,w) ((q)>(w)?(w):(q))
#define max(q,w) ((q)<(w)?(w):(q))
using namespace std;
typedef long long LL;
const int N=500,M=2e5,mo=1e9+7;
int read(int &n)
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int m,n,ans,m1;
LL f[N*2][N];
int B[M][3],A[N],B0;
struct scB
{
int s,p,c,S,w;
}sc[M],ak[M*10];
LL sump[N];
LL Ans[N][5],Ans1[M*10];
bool PX(scB q,scB w){return q.p<w.p;}
void link(int q,int w,int e)
{
B[++B0][0]=A[q],A[q]=B0,B[B0][1]=w,B[B0][2]=e;
}
LL ksm(LL q,int w)
{
LL ans=1;
for(;w;w>>=1,q=q*q%mo)if(w&1)ans=ans*q%mo;
return ans;
}
void Gaoxy(int n)
{
fo(i,1,n)f[i+n][i]=1;
fo(i,1,n)
{
int q=0;
fo(j,i,n)if(f[j][i]){q=j;break;}
if(!q)continue;
if(q!=i)fo(j,1,n)swap(f[i][j],f[q][j]),swap(f[i+n][j],f[q+n][j]);
LL t=ksm(f[i][i],mo-2);
fo(j,1,n)f[i][j]=f[i][j]*t%mo,f[i+n][j]=f[i+n][j]*t%mo;
fo(j,i+1,n)
{
LL t1=f[j][i]%mo;
if(t1)fo(k,1,n)
{
if(f[j][k]||f[i][k])f[j][k]=(f[j][k]-t1*f[i][k])%mo;
if(f[j+n][k]||f[i+n][k])f[j+n][k]=(f[j+n][k]-t1*f[i+n][k])%mo;
}
}
}
fod(i,n,1)if(f[i][i])
{
fo(j,1,i-1)
{
LL t=f[j][i];
if(t)fo(k,1,n)
{
if(f[j][k]||f[i][k])f[j][k]=(f[j][k]-f[i][k]*t)%mo;
if(f[j+n][k]||f[i+n][k])f[j+n][k]=(f[j+n][k]-f[i+n][k]*t)%mo;
}
}
}
}
int main()
{
int q,w,e;
read(n),read(m),read(m1);
fo(i,1,m)
{
read(q),read(w),read(e),read(sc[i].s),read(sc[i].c),read(sc[i].p);
if(q==n){sc[i].s=1e9;continue;}
link(q,w,e);
sc[i].w=e;sc[i].S=q;
// f[w][q]-=e;
sump[q]+=e;
}
fo(i,1,n)sump[i]=ksm(sump[i],mo-2),f[i][i]=1;
fo(i,1,n-1)efo(j,i)f[B[j][1]][i]=(f[B[j][1]][i]-sump[i]*B[j][2])%mo;
Gaoxy(n);
fo(i,1,n)fo(j,1,n)f[i][j]=f[j+n][i];
sort(sc+1,sc+1+m,PX);
for(;m&&sc[m].s>=1e9;--m);
fo(i,1,m)
{
sc[i].c=(LL)sc[i].c*sump[sc[i].S]%mo*(LL)sc[i].w%mo;
sc[i].s=(LL)sc[i].s*sump[sc[i].S]%mo*(LL)sc[i].w%mo;
fo(j,1,n)
{
Ans[j][0]=(Ans[j][0]+f[j][sc[i].S]*(LL)sc[i].c)%mo;
Ans[j][1]=(Ans[j][1]+f[j][sc[i].S]*(LL)sc[i].s%mo*sc[i].p)%mo;
Ans[j][3]=(Ans[j][3]+f[j][sc[i].S]*sc[i].s)%mo;
}
}
fo(i,1,m1)read(ak[i].p),read(ak[i].S),ak[i].s=i;
sort(ak+1,ak+1+m1,PX);
q=1;
fo(i,1,m1)
{
for(;q<=m&&sc[q].p<=ak[i].p;++q)
{
fo(j,1,n)
{
Ans[j][1]=(Ans[j][1]-f[j][sc[q].S]*(LL)sc[q].s%mo*sc[q].p)%mo;
Ans[j][2]=(Ans[j][2]+f[j][sc[q].S]*(LL)sc[q].s%mo*sc[q].p)%mo;
Ans[j][3]=(Ans[j][3]-f[j][sc[q].S]*sc[q].s)%mo;
Ans[j][4]=(Ans[j][4]+f[j][sc[q].S]*sc[q].s)%mo;
}
}
w=ak[i].S;
Ans1[ak[i].s]=(Ans[w][0]+Ans[w][1]-Ans[w][3]*ak[i].p-Ans[w][2]+Ans[w][4]*ak[i].p)%mo;
}
fo(i,1,m1)printf("%lld\n",(Ans1[i]+mo)%mo);
return 0;
}