Description

Kitty is a little cat. She is crazy about a game recently.

There arenscenes in the game(mark from 1 ton). Each scene has a numberpi. Kitty's score will become least_common_multiple(x,pi) when Kitty enter theithscene.xis the score that Kitty had previous. Notice that Kitty will become mad If she go to another scene but the score didn't change.

Kitty is staying in the first scene now(withp1score). Please find out how many paths which can arrive at thenthscene and haskscores at there. Of course, you can't make Kitty mad.

We regard two paths different if and only if the edge sequence is different.

Input

There are multiple test cases. For each test case:

The first line contains three integern(2 ≤n≤ 2000),m(2 ≤m≤ 20000),k(2 ≤k≤ 106). Then followed bymlines. Each line contains two integeru,v(1 ≤u,v≤ n, u ≠ v) indicate we can go tovthscene fromuthscene directly. The last line of each case contains n integerpi(1 ≤pi≤ 106).

Process to the end of input.

Output

One line for each case. The number of paths module 1000000007.

题目大意:有n个点m条无向边,每个点有一个分值p[i],设x为当前分值,每经过一个点,分值就会变成LCM(x, p[i]),若经过一个点的时候分值没有变化,那么这个点不能走。现在要从点1走到点n,要得到k的分值,问有多少种方法。

思路:首先走的每一步都必须是k的约数(不然到达终点的时候不可能得到k),那么走到每个点上至多有sum{k的约数}的分值,把k离散化,k最多有2*sqrt(k)个约数,即2000个。然后开始DP,dp[i][j]表示走到第i个点,得到分值j(离散值),并且能走到终点的方案数。然后记忆化搜索即可。原图有环也无所谓,因为分值每走一步必须要变化,而且只会越来越大,不会走出环来。

代码(120MS):

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
using namespace std; typedef long long LL; const int MAXN = ;
const int MAXE = ;
const int MOD = ; map<int, int> mp; int n, m, k, ecnt;
int head[MAXN];
int to[MAXE], next[MAXE];
int dp[MAXN][MAXN], val[MAXN]; void init() {
memset(head, , sizeof(head));
ecnt = ;
} inline void add_edge(int u, int v) {
to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++;
} LL gcd(LL a, LL b) {
return b ? gcd(b, a % b) : a;
} LL lcm(LL a, LL b) {
return a * b / gcd(a, b);
} inline void get_app() {
mp.clear();
int cnt = ;
for(int i = ; i * i <= k; ++i) {
if(k % i != ) continue;
mp[i] = ++cnt;
if(i * i != k) mp[k / i] = ++cnt;
}
} int dfs(int u, LL x) {
if(u == n && x == k) return ;
int now = mp[x];
if(dp[u][now] != -) return dp[u][now];
dp[u][now] = ;
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(k % val[v] != ) continue;
LL tmp = lcm(x, val[v]);
if(tmp == x || tmp > k) continue;
dp[u][now] = (dp[u][now] + dfs(v, tmp)) % MOD;
}
return dp[u][now];
} int main() {
while(scanf("%d%d%d", &n, &m, &k) != EOF) {
init();
while(m--) {
int u, v;
scanf("%d%d", &u, &v);
add_edge(u, v);
}
for(int i = ; i <= n; ++i) scanf("%d", &val[i]);
get_app();
memset(dp, , sizeof(dp));
int ans = (k % val[]) ? : dfs(, val[]);
cout<<ans<<endl;
}
}

最新文章

  1. 重撸js_2_基础dom操作
  2. Linux下安装使用Solr
  3. 设置XtraForm标题居中
  4. div 指令
  5. 开发板支持wifi
  6. Ioc-Autofac实现自动的注入
  7. HDU 3037 Saving Beans(Lucas定理模板题)
  8. Kafka集群模式部署
  9. hdoj-2023
  10. bzoj3405:[Usaco2009 Open]Grazing2 移动牛棚
  11. ThinkPhp调用webservice
  12. 使用JQuery插件,排序Gridview的某个字段
  13. 搜索广告与广告网络Demand技术-流式计算平台
  14. HDU 5769 Substring
  15. java.lang.OutOfMemoryError: PermGen space有效解决方法
  16. C++的一些知识
  17. PHP 使用 ElasticSearch
  18. 51 IP核查询
  19. 【模板/经典题型】树上第k大
  20. python基础学习1-列表使用

热门文章

  1. 1.Redis介绍以及安装
  2. Colored Boots题解
  3. 【模板】RMQ(计算区间最值)
  4. hdu 1394 Minimum Inversion Number(逆序数对) : 树状数组 O(nlogn)
  5. 关于linux‘RedHat6.9在VMware虚拟机中的安装步骤
  6. iOS 清理Xcode项目中没有使用到的图片资源和类文件
  7. 纯js轮播图练习-3,类似于淘宝海报带小圆点轮播图
  8. Qt上FFTW組件的编译与安裝
  9. 《PHP框架Laravel学习》系列分享专栏
  10. go基础语法-循环语句