标签:des style blog os io 数据 for 2014
Description
Input
Output
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 <map>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
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<int,int> 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;
}
HDU - 2254 奥运 (求等比数列和),布布扣,bubuko.com
标签:des style blog os io 数据 for 2014
原文地址:http://blog.csdn.net/u011345136/article/details/38279857