这题一看我就先想着t*m的分层图dp,dp[i][j][k]代表第t秒第j个点的路径数,k=0就是在第j个点爆炸,k=1就是停留在j点,然后
dp[i][j][1]=dp[i-1][j][1]+∑(其他相邻点v,dp[i-1][v][1]),意思是第i秒停留在第j个点的路径可以是第i-1秒停留在第j个点或和j相邻点转移过来
dp[i][j][0]=dp[i-1][j][1],意思是在第i秒第j个点爆炸的点只能是第i-1秒停留在第j个点转移来
然后把每秒爆炸的方案加上,再加上第t秒停留在每个点的方案就是答案
然后我就是开始写了。。然后样例过了。。然后我就开始交。。。然后人没了
一直t一直t,t到怀疑人生
然后我就试了下题解的分层dp代码,然后也t了,应该是加强了数据。
告辞
(话说洛谷评测机真8太行,1s1e8都跑不了)
那就只能矩阵快速幂了,邻接矩阵的k次幂的到mp[][],mp[i][j]意思是第i个点到第j个点路径长度为k的走法有多少种
于是这题不就是要求点1走t次到其他点的总方案吗
不过还有两个地方要处理
1.它可以在某个点停留
那我们只要给每个点增加一个自环,那就可以达到在某个点停留的效果
2.它可以自爆
那只要给每个点和0连一条边,0本身没有出边,那每个点到0就不能出去,相当于自爆了
最后ans= ,
题目描述
加里敦星球的人们特别喜欢喝可乐。因而,他们的敌对星球研发出了一个可乐机器人,并且放在了加里敦星球的 111 号城市上。这个可乐机器人有三种行为: 停在原地,去下一个相邻的城市,自爆。它每一秒都会随机触发一种行为。现在给加里敦星球城市图,在第 000 秒时可乐机器人在 111 号城市,问经过了 ttt 秒,可乐机器人的行为方案数是多少?
输入格式
第一行输入两个正整数 NNN,MMM。NNN 表示城市个数,MMM 表示道路个数。
接下来 MMM 行每行两个整数 uuu,vvv,表示 uuu,vvv 之间有一条道路。保证两座城市之间只有一条路相连,且没有任何一条道路连接两个相同的城市。
最后一行是一个整数 ttt,表示经过的时间。
输出格式
输出可乐机器人的行为方案数,答案可能很大,请输出对 201720172017 取模后的结果。
输入输出样例
输入 #1
3 2 1 2 2 3 2
输出 #1
8
说明/提示
样例输入输出 1 解释
- 111 ->爆炸。
- 111 -> 111 ->爆炸。
- 111 -> 222 ->爆炸。
- 111 -> 111 -> 111。
- 111 -> 111 -> 222。
- 111 -> 222 -> 111。
- 111 -> 222 -> 222。
- 111 -> 222 -> 333。
数据范围与约定
- 对于 20%20\%20% 的数据,保证 t≤1000t \leq 1000t≤1000。
- 对于100%100\%100%的数据,保证 1<t≤1061 < t \leq 10^61<t≤106,1≤N≤301 \leq N \leq301≤N≤30,0<M<1000 < M < 1000<M<100,1≤u,v≤N1 \leq u, v \leq N1≤u,v≤N。
#include <cstdio> #include<iostream> #include<cstring> #include<map> using namespace std; typedef long long ll; const ll mod = 2017; map<ll,ll>mp; inline ll read(){ ll x = 0;char c = 0; c = getchar(); while(isdigit(c)) x = (x<<1)+(x<<3)+(c^48),c = getchar(); return x; } struct matrix{ ll x[31][31]; }a; matrix muli(matrix a,matrix b){ matrix temp; memset(temp.x,0,sizeof(temp.x)); for(register int i = 0; i <=30; i++) for(register int j = 0; j <=30; j++) for(register int k = 0; k <=30; k++){ temp.x[i][j]+=a.x[i][k]*b.x[k][j]; temp.x[i][j]%=mod; } return temp; } matrix pows(matrix a,ll b){ matrix e; memset(e.x,0,sizeof(e)); for(register int i = 0; i <=30; i++) e.x[i][i] = 1; matrix ans = e; while(b){ if(b&1) ans=muli(ans,a); a=muli(a,a); b>>=1; } return ans; } int main() { /*ll n,q; q = read(),n = read(); matrix a; a.x[0][0] = 3;a.x[0][1] = 1;a.x[1][0] = 1;a.x[1][1] = 0; matrix b; b.x[0][0] = 3;b.x[0][1] = 1;b.x[1][0] = 2;b.x[1][1] = 0; ll ans = 0; matrix a1,b1; mp[0] = 0;mp[1] = 1; for(register ll i = 1; i <= q; i++){ if(mp.count(n)==0){ b1=pows(b,n-2); a1=muli(a,b1); ans=ans^a1.x[0][0]; mp[n] = a1.x[0][0]; n=n^(a1.x[0][0]*a1.x[0][0]); }else{ ans^=mp[n]; n^=(mp[n]*mp[n]); } } printf("%lld\n",ans);*/ ll n,m; scanf("%lld %lld",&n,&m); for(ll i=1;i<=m;i++) { ll u,v; scanf("%lld %lld",&u,&v); a.x[u][v]=1;a.x[v][u]=1; } for(ll i=0;i<=n;i++)a.x[i][i]=1; for(ll i=1;i<=n;i++) { a.x[i][0]=1; } ll t; scanf("%lld",&t); matrix b=pows(a,t); ll ans=0; for(ll i=0;i<=n;i++) ans=(ans+b.x[1][i])%2017; printf("%lld\n",ans); return 0; }