松鼠配对?

题意:

给出一张无向图,有n(<=100)个点,m条边,这n个点上一开始有ai个特殊点,这些特殊点一个单位时间移动一次,求移动T(<=1e9)次后,每个点上的点对的期望值(答案对1e9+7)取模(假如一个点上有4个特殊点,那么这个点上就有6个点对)。

题解:

首先看到T的数据范围,这个提示的是要用log级别的算法,很容易就想到了矩阵,现在的问题就是验证矩阵是否可行。

很容易知道初始矩阵是n * n的,那么这个矩阵表示的是什么?很容易知道是表示概率,因为刚好满足了乘法原理和加法原理,到此说明矩阵是可行的。

用矩阵就可以知道一个点到达另外一个点的概率,而E = P * w,现在可以很容易得到一个点到达另外一个点的期望值。

但是要求的却是 点对的期望值,那么就是两个点间的期望值相乘,现在的问题就是求到达此点的所有点的期望值的两两之积,由公式[(a+b+c+d...)2 - a2 - b2 - c2 - d2 - ...]/ 2可以容易得到。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define LL long long
const int N = 1e3 + 7;
const int mod = 1e9 + 7;
struct Matrix
{
	LL map[107][107];
} F;

LL inv[N], ans, a[N][N];
int n, c[N][N], num[N], T;

Matrix Mul (Matrix a, Matrix b)
{
	Matrix ret;
	memset (ret.map, 0, sizeof ret.map);
	for (int i = 1; i <= n; ++ i)
		for (int j = 1; j <= n; ++ j)
			for (int k = 1; k <= n; ++ k)
				ret.map[i][j] = (ret.map[i][j] + a.map[i][k] * b.map[k][j] % mod) % mod;
	return ret;
}

Matrix Pow (Matrix x, int cnt)
{
	Matrix ret;
	memset (ret.map, 0, sizeof ret.map);
	for (int i = 0; i <= n; ++ i) ret.map[i][i] = 1;
	while (cnt)
	{
		if (cnt & 1) ret = Mul(ret, x);
		x = Mul(x, x);
		cnt >>= 1;
	}
	return ret;
}

LL pow (LL x, int n)
{
	LL ret = 1;
	while (n)
	{
		if (n & 1) ret = ret * x % mod;
		x = x * x % mod;
		n >>= 1;
	}
	return ret;
}

int main ()
{
	scanf ("%d%d", &n, &T);
	for (int i = 1; i <= n; ++ i) scanf ("%d", &num[i]);

	for (int i = 1; i <=1000; ++ i) inv[i] = pow (i, mod - 2);

	for (int i = 1; i <= n; ++ i)
		for (int j = 1; j <= n; ++ j)
			scanf ("%d", &c[i][j]);
	for (int i = 1; i <= n; ++ i)
	{
		int cnt = 0;
		for (int j = 1; j <= n; ++ j) cnt += c[i][j];
		for (int j = 1; j <= n; ++ j) a[i][j] = c[i][j] * inv[cnt];
	}
	if (T != 1)
	{
		for (int i = 1; i <= n; ++ i)
			for (int j = 1; j <= n; ++ j)
				F.map[i][j] = a[i][j];
		F = Pow (F, T);
		for (int i = 1; i <= n; ++ i)
			for (int j = 1; j <= n; ++ j)
				a[i][j] = F.map[i][j];
	}
	for (int i = 1; i <= n; ++ i)
	{
		LL ret1 = 0, ret2 = 0;
		for (int j = 1; j <= n; ++ j)
		{
			LL ret = (a[j][i] * num[j]) % mod;
			ret1 = (ret1 + ret) % mod;
			ret2 = (ret2 + ret * a[j][i]) % mod;
		}
		ans = (ans + (ret1 * ret1 - ret2 + mod) % mod * inv[2] % mod) % mod;
	}
	cout << ans << endl;
	return 0;
}

  

总结:

1.这个题个人觉得不是很难,但是暴露出概率和期望确实学得不是一般的水啊~

2.这个矩阵就写得很蠢了,明明可以直接用数组写,而且还可能更快。

时间: 2024-10-16 14:43:40

松鼠配对?的相关文章

bzoj-3170 3170: [Tjoi 2013]松鼠聚会(计算几何)

题目链接: 3170: [Tjoi 2013]松鼠聚会 Time Limit: 10 Sec  Memory Limit: 128 MB Description 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. Input 第一行给出数字N,表示有多少只小松鼠.0<=N<=10^5下面N行,每行给出x,y表示其家的坐标.-10^9<=x,y<=10^

南阳OJ-2 括号配对 (数据结构-栈的应用)

括号配对问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 现在,有一行括号序列,请你检查这行括号是否配对. 输入 第一行输入一个数N(0<N<=100),表示有N组测试数据.后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组.数据保证S中只含有"[","]","(",")"四种字符 输出 每组输入数据的输出占一行,

1485 字符配对

codevs——1485 字符配对 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze 题解 题目描述 Description 在一个字符串中,把相同的字符两两删除,求剩下字符的个数. 例如:字符串asasda, 首先删除两个'a',得到字符串'ssda'. 然后删除两个's',得到字符串'da'. 此时,字符串中没有了相同的字符,删除结束,剩下个数为2. 输入描述 Input Description 一个字符串,含义如描述所示. 输出描述 Output Des

Bzoj1237 [SCOI2008]配对

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1446  Solved: 551 Description 你有n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一 个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配 对.例如A={5,6,8},B={5,7,8},则最优配对方案是5配8, 6配5, 8配7,配对整数 的差的绝对值分别为2, 2, 1,和为5.注意,5配5,6配7,8配8是不允许的,因 为

Android蓝牙自动配对Demo,亲测好使!!!

蓝牙自动配对,即搜索到其它蓝牙设备之后直接进行配对,不需要弹出配对确认框或者密钥输入框. 转载请注明出处http://blog.csdn.net/qq_25827845/article/details/52400782 经过最近一段时间得研究,针对网上给出的案例.总结了一个亲测好使的Demo. 说明如下: 1.本Demo用来连接蓝牙设备HC-05,如果你要连接其他蓝牙设备,注意修改相关名字以及修改设备初试pin值. 2.将Demo安装在Android手机上,点击按钮,可以实现与目标蓝牙设备的自动

【 网络流24 】飞行员配对方案问题

第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的 2 名飞行员,其中 1 名是英国飞行员,另 1 名是外籍飞行员.在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合.如何选择配对飞行的飞行员才能使一次派出最多的飞机.对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机. 对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员

SPSS数据分析—配对Logistic回归模型

Lofistic回归模型也可以用于配对资料,但是其分析方法和操作方法均与之前介绍的不同,具体表现 在以下几个方面1.每个配对组共有同一个回归参数,也就是说协变量在不同配对组中的作用相同2.常数项随着配对组变化而变化,反映了非实验因素在配对组中的作用,但是我们并不关心其大小, 因此在拟合时采用条件似然函数代替了一般似然函数,从而在拟合中消去了反映层因素的参数. SPSS中没有直接拟合配对Logistic回归模型的过程,需要对数据进行一些处理,采用其他方法进行拟合,拟合方法有变量差值拟合和COX模型

android 打开蓝牙设备 显示已经配对的蓝牙设备 ,并将已配对的蓝牙设备显示在textview中

(1)要想使用android 手机的Bluetooth,需要在androidmanifest文件中加入使用蓝牙的权限. <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 注意:权限应该添加在androidmanifest文件中&

蓝牙简单配对(Simple Pairing)协议及代码流程简述

kangear注: 文章转自:http://blog.csdn.net/myxmu/article/details/12217135 原文把图给搞丢了,但是文章太好了,这个时候我就发挥多年的Google和人脉关系根据链接找到了,补上图(这个图是MTK内部用图). [DESCRIPTION] 在BT2.1及之后版本,蓝牙协议有在传统的密码配对(PIN Code Pairing)之外,新增一种简单配对(Simple Pairing)的方式.这种新的配对方式操作更为简单.安全性也更强.目前市面上大部分