UpdateAfterEvent
2017-09-15 20:45
267 查看
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[][]
枚举终点和一个端点就行了
题目中要求取模,要除的话直接模逆元
玉米、饼干,可谓来者不拒,憨态可掬的模样吸引了众多围观者...
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[][]
枚举终点和一个端点就行了
题目中要求取模,要除的话直接模逆元
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long lol; struct Matrix { lol a[1002][1002]; }Mat,ans; int Mod=1000000007; lol n,T; lol v[1001]; int map[1001][1001]; lol A[1001],f[1001][1001],anss; Matrix operator *(const Matrix &x,const Matrix &y) { Matrix res; int i,j,k; memset(res.a,0,sizeof(res.a)); for (i=1;i<=n;i++) { for (j=1;j<=n;j++) { for (k=1;k<=n;k++) { res.a[i][j]+=(x.a[i][k]*y.a[k][j])%Mod; res.a[i][j]%=Mod; } } } return res; } void pow(int x) {int i; for (i=1;i<=n;i++) ans.a[i][i]=1; while (x) { if (x&1) ans=ans*Mat; Mat=Mat*Mat; x/=2; } } int main() {int i,j; cin>>n>>T; for (i=1;i<=n;i++) { scanf("%lld",&v[i]); } for (i=1;i<=n;i++) { for (j=1;j<=n;j++) { scanf("%d",&map[i][j]); } } A[1]=1; for (i=2;i<=1000;i++) A[i]=((Mod-Mod/i)*A[Mod%i])%Mod; memset(Mat.a,0,sizeof(Mat.a)); for (i=1;i<=n;i++) { int cnt=0; for (j=1;j<=n;j++) if (map[i][j]) cnt++; for (j=1;j<=n;j++) if (map[i][j]) Mat.a[i][j]=A[cnt]; } if (T>1) pow(T); for (i=1;i<=n;i++) { for (j=1;j<=n;j++) f[i][j]=ans.a[i][j]; } if (T==1) for (i=1;i<=n;i++) for (j=1;j<=n;j++) f[i][j]=Mat.a[i][j]; for (i=1;i<=n;i++) { lol ret1=0,ret2=0,ret3; for (j=1;j<=n;j++) { lol tmp=(f[j][i]*v[j])%Mod; ret1=(ret1+tmp)%Mod; ret2=(ret2+tmp*f[j][i])%Mod; } ret3=((ret1*ret1)%Mod-ret2+Mod)%Mod; anss+=(ret3*A[2])%Mod; anss%=Mod; } cout<<anss; }
相关文章推荐
- as3 updateAfterEvent的作用
- Mouse e.updateAfterEvent 函数
- as3 updateAfterEvent的作用
- as3 updateAfterEvent的作用
- setInterval()/clearInterval()/updateAfterEvent()
- (转)as3 updateAfterEvent的作用
- updateAfterEvent的用处
- updateAfterEvent
- stage.invalidate()、event.updateAfterEvent()对渲染的影响
- as3 updateAfterEvent的作用
- 一些动画效果用使用 updateAfterEvent
- Android 23 Connot resolve method updateNotification.setLatestEventInfo()解决方案
- Disable Restart Now Message After Windows Automatic Update Message
- oracle触发器after update of |更改之后赋值|
- How To Disable Automatic Restart after Windows Update
- attempt to create saveOrUpdate event with null entity
- Google: Even After Algorithm Update, Your Rankings Changes May Not Be Immediately Visible
- MySQL半同步--after_send_event与after_reset_master
- When you publish a workflow in Microsoft Dynamics CRM 4.0 after you install Update Rollup 2, you receive Error message
- HTTP Status 500 - attempt to create saveOrUpdate event with null entity的错误及解决办法