设为首页 加入收藏

TOP

HDU - 2254 奥运 (求等比数列和)
2015-07-20 18:02:14 来源: 作者: 【 】 浏览:3
Tags:HDU 2254 奥运 等比 数列

Description

北京迎来了第一个奥运会,我们的欢呼声响彻中国大地,所以今年的奥运金牌 day day up!
比尔盖兹坐上鸟巢里,手里摇着小纸扇,看的不亦乐乎,被俺们健儿的顽强拼搏的精神深深的感动了。反正我的钱也多的没地方放了,他对自己说,我自己也来举办一个奥运会,看谁的更火。不过他的奥运会很特别:
1 参加人员必须是中国人;
2 至少会加法运算(因为要计算本人获得的金牌数)
他知道中国有很多的名胜古迹,他知道自己在t1 到 t2天内不可能把所有的地方都玩遍,所以他决定指定两个地方v1,v2,如果参赛员能计算出在t1到t2天(包括t1,t2)内从v1到v2共有多少种走法(每条道路走需要花一天的时间,且不能在某个城市停留,且t1=0时的走法数为0),那么他就会获得相应数量的金牌,城市的总数<=30,两个城市间可以有多条道路
,每条都视为是不同的。

Input

本题多个case,每个case:
输入一个数字n表示有n条道路 0 接下来n行每行读入两个数字 p1,p2 表示城市p1到p2有道路,并不表示p2到p1有道路 (0<=p1,p2<2^32)
输入一个数字k表示有k个参赛人员
接下来k行,每行读入四个数据v1,v2,t1,t2 (0<=t1,t2<10000)

Output

对于每组数据中的每个参赛人员输出一个整数表示他获得的金牌数(mod 2008)

Sample Input

 6
1 2
1 3
2 3
3 2
3 1
2 1
3
1 2 0 0
1 2 1 100
4 8 3 50 

Sample Output

 0
1506
0 

思路:矩阵的基本应用之一:我们都知道s[a][b]可以代表一步从a到b的路径数,那么矩阵的n次方就代表走n步的路径数。又偷了个模板

#include 
#include 
    
      #include 
     
       #include 
      
        #include 
       
         using namespace std; const int maxn=35; const int mod=2008; class Matrix { public: int a[maxn][maxn]; int n; void init(int x) { memset(a,0,sizeof(a)); if (x) for (int i = 0; i < maxn ; i++) a[i][i] = 1; } Matrix operator +(Matrix b) { Matrix c; c.n = n; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) c.a[i][j] = (a[i][j] + b.a[i][j]) % mod; return c; } Matrix operator +(int x) { Matrix c = *this; for (int i = 0; i < n; i++) c.a[i][i] += x; return c; } Matrix operator *(Matrix b) { Matrix p; p.n = b.n; p.init(0); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) for (int k = 0; k < n; k++) p.a[i][j] = (p.a[i][j] + (a[i][k]*b.a[k][j])%mod) % mod; return p; } Matrix power(int t) { Matrix ans,p = *this; ans.n = p.n; ans.init(1); while (t) { if (t & 1) ans=ans*p; p = p*p; t >>= 1; } return ans; } }a; map
        
          mp; //分治求(a^1+a^2+...+.a^n)%mod Matrix Cal(Matrix a,int n) { if (n == 1) return a; if (n & 1) return a.power(n) + Cal(a, n-1); else return Cal(a, n/2) * (a.power(n/2) + 1); } int main() { int n,m; while (scanf("%d",&n) != EOF) { a.init (0); mp.clear(); int id = 0, u, v, t1, t2; for (int i = 0; i < n; i++) { scanf("%d%d",&u,&v); if (mp.find(u) == mp.end()) mp[u]=id++; if (mp.find(v) == mp.end()) mp[v]=id++; a.a[mp[u]][mp[v]]++; } a.n = id; scanf("%d",&m); while (m--) { scanf("%d%d%d%d",&u,&v,&t1,&t2); if (mp.find(u)==mp.end() || mp.find(v)==mp.end()) { printf("0\n"); continue; } if (t1 > t2) swap(t1,t2); int s = mp[u],t = mp[v]; if (t1 == 0) { if (t2 == 0) printf("0\n"); else printf("%d\n",Cal(a,t2).a[s][t]); } else if (t1 == 1) { printf("%d\n",Cal(a,t2).a[s][t]); } else { int ans = Cal(a,t2).a[s][t]-Cal(a,t1-1).a[s][t]; ans = (ans%mod + mod)%mod; printf("%d\n",ans); } } } return 0; }
        
       
      
     
    




】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇CF 17B Hierarchy 下一篇HDU 4893 Wow! Such Sequence!(线..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: