题解 P4102 【[HEOI2014]林中路径 】
咕了几天终于来了~
这个题首先看数据范围发现是
大体的思路是递归,先求出
简单起见,这里只讨论
而对于最长路径限制为
不妨令原图的邻接矩阵为
同理更有
那么只要在递归过程中记录
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define mod 1000000007
using namespace std;
typedef long long ll;
const int MAXN = 105;
inline int readint()
{
int res = 0, f = 1;
char c = 0;
while(!isdigit(c))
{
c = getchar();
if(c=='-')
f = -1;
}
while(isdigit(c))
res = res*10+c-'0', c = getchar();
return res*f;
}
int n,m,k,q;
inline int modd(int x)
{ return x>=mod?x-mod:x; }
struct Mat
{
int a[MAXN][MAXN];
Mat()
{ memset(a,0,sizeof(a)); }
Mat operator+(const Mat t) const
{
Mat res;
for(int i = 1; i<=n; i++)
for(int j = 1; j<=n; j++)
res.a[i][j] = modd(a[i][j]+t.a[i][j]);
return res;
}
Mat operator*(const Mat t) const
{
Mat res;
for(int i = 1; i<=n; i++)
for(int j = 1; j<=n; j++)
if(t.a[i][j])
for(int k = 1; k<=n; k++)
res.a[i][k] = (1ll*res.a[i][k]+1ll*a[j][k]*t.a[i][j])%mod;
return res;
}
Mat operator*(const int t) const
{
Mat res;
for(int i = 1; i<=n; i++)
for(int j = 1; j<=n; j++)
res.a[i][j] = 1ll*a[i][j]*t%mod;
return res;
}
}G,c,ans0,ans1,ans2;
inline Mat unit()
{
Mat res;
for(int i = 1; i<=n; i++)
res.a[i][i] = 1;
return res;
}
inline void solve(int t)
{
if(t==1)
{
c = G, ans0 = unit();
return;
}
solve(t/2);
int x = t/2;
ans2 = ans2+ans2*c+ans1*c*(2*x)+ans0*c*(1ll*x*x%mod);
ans1 = ans1+ans1*c+ans0*c*x;
ans0 = ans0+ans0*c;
c = c*c;
if(t&1)
{
ans0 = ans0+c;
ans1 = ans1+c*(t-1);
ans2 = ans2+c*(1ll*(t-1)*(t-1)%mod);
c = c*G;
}
}
int main()
{
n = readint(), m = readint(), k = readint(), q = readint();
for(int i = 1; i<=m; i++)
{
int u = readint(), v = readint();
G.a[u][v]++;
}
solve(k+1);
while(q--)
{
int x = readint(), y = readint();
printf("%d\n",ans2.a[x][y]);
}
return 0;
}