UpdateAfterEvent

10月3日,在杭州市西湖景区,一只小松鼠不停地接受一道道食物,花生、
玉米、饼干,可谓来者不拒,憨态可掬的模样吸引了众多围观者...
Description  
 小松鼠打了10个小时的游戏,一脸满足。却发现周围再次围满了游客,
逃!
 她发现整个西湖内的松鼠都以相同的速度在树之间跳跃。每跳跃一次花
费一个单位的时间。我们可以把西湖抽象为一张n个点的无向图,初始时
每个点上都有若干只松鼠,它们每单位时间都可以沿着一条无向边进行跳
跃。
 对于一只当前在点i的松鼠,它在接下来的一个单位时间内等概率向相邻
的点跳跃。更具体地讲,我们称与点i通过一条无向边直接相连的点为与i相
邻的点,假设这样的点有p个,那么对于每一个与i相邻的点,在下一时刻都
有 1/p 的概率跳到它。
 超萌小松鼠已知初始时刻(0时刻)每棵树上的松鼠分布情况,她想知道
在T时刻,在同一棵树上的松鼠对数的期望。关于“松鼠对数”的解释:假
设有4只松鼠在同一棵树上,那么我们称有6对在同一棵树上的松鼠。
 为了避免精度误差,我们将答案模10^9 + 7输出。
Input  
 第一行三个数n, T 。 意义如题面中所述。  接下来一行n个数, 第i个
数a i 表示第i个点初始时刻有a i 只松鼠。 接下来n行,每行n个数,第i行
第j个数如果为1表示点i与点j间有无向边相连,为0则表示没有。
Output  
 输出一行一个数,表示T时刻在同一棵树上的松鼠对数的期望在模10 9 +
7意义下的答案。6
Constraints  
 对于前30%,n <= 10, T <= 30
 对于前50%,n <= 100, T <= 30
 对于100%,n <= 100, T <= 10^9

题解:

大家能够发现,尽管可能大家最先想到的计算松鼠对数的方法,是根据树上的松鼠总数x,

通过x * (x - 1) / 2来得到。但不妨考虑一下一个更一般的方法:
    枚举一只松鼠,再枚举另一只松鼠,如果它们在同一棵树上则答案加一。

从这个方法中能够得到的启示是:松鼠对数这个量实际上是相对独立的,即与这两只松鼠之外的量并无直接的关系。这样就避免了我们陷入一味考虑如何计算“松鼠期望总数”的错误方向了。

枚举一只松鼠A,再枚举另一只松鼠B,考虑它们同时存在在树i上的情况。
假设松鼠A在树i上的概率为P(A, i), 松鼠B在树i上的概率为P(B, i)
则它们同时存在于树i上的概率为P(A, i) * P(B, i)
而这一事件构成了“1对结束时在同一棵树上的松鼠”
因此对答案的贡献是 P(A, i) * P(B, i) * 1
我们只需要对于每一对松鼠枚举一下树i,然后对这些东西求和计入答案就可以了。

考虑如何计算P(A,i)。我们不妨假设f(i, j)为一只松鼠从点i出发,在点j停下的概率。
当T = 0时,f[i][i]均为1.0,每过一个单位时间时,考虑f[i][j]即松鼠当前在j时的概率
根据题中的描述向j的相邻点转移。
这样能够得到所有T <= 30的分数

观察可知,每次的转移事实上都是一样的。于是我们可以使用矩阵乘法来优化这个转移过程。

100分是给n^2计算期望的方法

首先

我们要求的是E(1)*E‘(1)/2+E(1)*E(2).....+E(1)*E(n)+E(2)*E‘(2)/2+E(2)*E(3)....

E‘指的是少一个松鼠的期望

如果直接枚举终点和两端点,将是n^3

但可以这样:原式=[(E(1)+E(2)+E(3)+E(4).....)^2-E(1)(E(1)-E‘(1))-E(2)(E(2)-E‘(2))....]/2

显然E(1)-E‘(1)=f[][]

枚举终点和一个端点就行了

题目中要求取模,要除的话直接模逆元

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long lol;
 7 struct Matrix
 8 {
 9     lol a[1002][1002];
10 }Mat,ans;
11 int Mod=1000000007;
12 lol n,T;
13 lol v[1001];
14 int map[1001][1001];
15 lol A[1001],f[1001][1001],anss;
16 Matrix operator *(const Matrix &x,const Matrix &y)
17 {
18       Matrix res;
19       int i,j,k;
20       memset(res.a,0,sizeof(res.a));
21       for (i=1;i<=n;i++)
22       {
23           for (j=1;j<=n;j++)
24           {
25               for (k=1;k<=n;k++)
26               {
27         res.a[i][j]+=(x.a[i][k]*y.a[k][j])%Mod;
28         res.a[i][j]%=Mod;
29               }
30           }
31       }
32       return res;
33 }
34 void pow(int x)
35 {int i;
36   for (i=1;i<=n;i++)
37     ans.a[i][i]=1;
38   while (x)
39     {
40       if (x&1) ans=ans*Mat;
41       Mat=Mat*Mat;
42       x/=2;
43     }
44 }
45 int main()
46 {int i,j;
47   cin>>n>>T;
48   for (i=1;i<=n;i++)
49     {
50       scanf("%lld",&v[i]);
51     }
52   for (i=1;i<=n;i++)
53     {
54       for (j=1;j<=n;j++)
55     {
56       scanf("%d",&map[i][j]);
57     }
58     }
59   A[1]=1;
60   for (i=2;i<=1000;i++)
61     A[i]=((Mod-Mod/i)*A[Mod%i])%Mod;
62   memset(Mat.a,0,sizeof(Mat.a));
63   for (i=1;i<=n;i++)
64     {
65       int cnt=0;
66       for (j=1;j<=n;j++)
67     if (map[i][j]) cnt++;
68       for (j=1;j<=n;j++)
69     if (map[i][j]) Mat.a[i][j]=A[cnt];
70     }
71   if (T>1)
72     pow(T);
73   for (i=1;i<=n;i++)
74     {
75       for (j=1;j<=n;j++)
76     f[i][j]=ans.a[i][j];
77     }
78   if (T==1)
79     for (i=1;i<=n;i++)
80       for (j=1;j<=n;j++)
81     f[i][j]=Mat.a[i][j];
82   for (i=1;i<=n;i++)
83     {
84       lol ret1=0,ret2=0,ret3;
85       for (j=1;j<=n;j++)
86     {
87       lol tmp=(f[j][i]*v[j])%Mod;
88       ret1=(ret1+tmp)%Mod;
89       ret2=(ret2+tmp*f[j][i])%Mod;
90     }
91       ret3=((ret1*ret1)%Mod-ret2+Mod)%Mod;
92       anss+=(ret3*A[2])%Mod;
93       anss%=Mod;
94     }
95   cout<<anss;
96 }
时间: 2024-12-05 16:34:38

UpdateAfterEvent的相关文章

JavaScript中的setInterval用法

setInterval动作的作用是在播放动画的时,每隔一定时间就调用函数,方法或对象.可以使用本动作更新来自数据库的变量或更新时间显示.setInterval动作的语法格式如下:setInterval(function,interval[,arg1,arg2,......argn])setInterval(object,methodName,interval[,arg1,arg2,.....argn])第一种格式是标准动作面板中setInterval函数的默认语法,第二种格式是在专家模式动作中使

JavaScript浮动广告代码,容纯DIV/CSS对联漂浮广告代码,兼容性非常好的js右下角与漂浮广告代码

基于JavaScript代码实现随机漂浮图片广告,javascript图片广告 在网上有很多这样的代码,不过未必符合W3C标准,因为在头部加上<!DOCTYPE html>类似标签之后,漂浮效果就会失效,下面分享一个符合标准的漂浮代码,使需要的朋友免去大量改造代码的繁琐. 代码一: 代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name

JavaScript中setInterval的用法总结

setInterval动作的作用是在播放动画的时,每隔一定时间就调用函数,方法或对象.可以使用本动作更新来自数据库的变量或更新时间显示. setInterval动作的语法格式如下:setInterval(function,interval[,arg1,arg2,......argn])setInterval(object,methodName,interval[,arg1,arg2,.....argn]) 第一种格式是标准动作面板中setInterval函数的默认语法,第二种格式是在专家模式动作

课间操定时播音源代码

var array:Array = new Array(9, 11, 0, 9, 13, 36);var array1:Array = new Array(9, 11, 0, 9, 16, 0);var time:Date = new Date();taday = time.getDay();if (taday == 1) { for (i=1; i<=6; i++) {  if (Number(array1[i-1])<10) {   _root["T"+i] = &qu

FLASH动作脚本详解

FLASH动作脚本详解 一.FLASH脚本基础入门讲解 二.按钮AS的编写 三.影片剪辑的AS编写 四.动态文本框 五.影片剪辑的拖拽 六.流程控制与循环语句 七.绘图及颜色的AS的编写 八.声音 AS 的编写与控制 九.时间日期的 AS编写 十.点语法以及路径 十一.深入了解时间控制 十二.无条件转移 十三.变量 十四.运算符(一) 十五.变量(二) 十六.影片剪辑的属性 十七.再讲循环语句 十八.影片剪辑处理函数 十九.复制影片剪辑 二十.深入 startDrag()与 stopDrag()

as3中一些不常见的写法

mc.gotoAndPlay(Math.random()*10>>0); Math.random()*10 取10以内带小数的随机数.>>0 的功能去除小数点后的数,所以 Math.random()*10>>0 即获取10以内的随机整数 if(i&1){} i&1 的意思就是判断i是奇数还是偶数奇数2进制最后一位1, i&1=1 真偶数2进制最后一位0, i&1=0 假 var a:Array = new Array(); for (va

超少代码的头像裁剪上传

效果: as上传的好处在于裁剪工作在客户端就完成了,而用jcrop的话要记录裁剪大小,位置坐标等,传给服务端才能裁剪 代码很简单 1 package 2 { 3 import flash.display.*; 4 import flash.events.Event; 5 import flash.utils.ByteArray; 6 import flash.events.*; 7 import flash.net.*; 8 import com.adobe.images.JPGEncoder;

Adobe Scout 使用参考说明

Adobe Scout 用于优化 Flash 内容,是一款极为强大的工具,因为它能让您看到 Flash Player 幕后正在发生的事情.但是若明白 Flash Player 为什么做这些事情,您看到这些事情才会最有用.只有这样,您才能有效地找到修复 Scout 所告知的问题的方法! 本文的目的是让您大致了解 Flash Player 的工作原理,并将之与您在 Scout 中看到的信息相关联.本文也是 Scout 中所用术语的参考指南,因此您可以从中查找 Flash Player 执行的各种活动

as3.0 橡皮功能2

package com{ import flash.display.MovieClip; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.SimpleButton; import flash.events.MouseEvent; import flash.display.Shape; import flash.geom.Matrix; import flash.geom.Colo