时间限制 1s 空间限制 512MB

2.1 题目描述

“Allons-y!”

时间还算足够,好好看看题吧。

有一种说法,时间线是扭曲的,会相互交织。(一般在科幻片里比较流行?)

不管啦,反正现在有个蓝盒子,在时间线上随机游走。

记这个盒子一开始在时间线上的位置为 0,记当前位置为 pos,每一次穿梭,它

有 q 的概率到达 pos + 1,1 − q 的概率到达 pos − 1。

特别的,q 是一个有理数。

我们认为时间线的两端近乎在无穷远处,问 n 次穿梭后,蓝盒子离初始位置的

期望距离。

为了避免精度问题,这里采用取模来避免实数运算。

具体来说,输入会给出一个素数 p,而每次穿梭过程中从 pos 到达 pos + 1 的概

率 q 将在模意义下给出。(例如 q = ab ,这里保证 b, p 互素,读入的将是模意义下



的 ab )

2.2 输入格式

一行三个正整数 n, q, p,分别表示穿梭的次数、模 p 意义下的概率 q 和模数 p。

2.3 输出格式

一行一个整数,为蓝盒子离初始位置的期望距离在模意义下的值。

2.4 样例输入

100 1 1000000207

2.5 样例输出

100

42.6 数据规模和约定

对于全部的数据,10 9 ≤ p ≤ 2 × 10 9 且 p 为素数,0 ≤ q ≤ p − 1

对于 20% 的数据,n ≤ 15。

对于另外 30% 的数据,n ≤ 1000。

对于剩下 50% 的数据,n ≤ 5 × 10 4 。

【题解】

这道题我考试时连题目都没看懂。。。

然而考完后发现此题不难。。。

*先科普一下费马小定理:

特别的,当p为素数时,x无法被p整除,φ(p)=p-1,于是便有费马小定理Xp-1≡1(mod p)

在p是素数时,对任意正整数x都有Xp≡X(mod p)

于是对于a的逆元x,有ax≡1(mod m),对于a,m互素且m为素数时,有x=am-2,于是我们可以通过快速幂快速求出a的逆元。

另外,借助素数筛,我们还可以很快的求出1-n的欧拉函数值。每当我们找到一个素数,就把他的倍数的欧拉函数值乘上(p-1)/p.

而且,借助费马小定理我们可以实现对除法取模。*

这道题的模意义下,指的是把除法变成乘法,把a/b变成a*(1/b),而1/b是b的逆元。

这道题就变成数学问题了。

公式为f[n]=∑(n i=0)q^i*(1-q)^(n-i)C(n,i)|n−2×i|

然而我似乎不太理解这个公式,有时间再看吧。。(逃~~)

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll (long long)
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
const int Maxn=50005;
int n,q,p;
int fac[Maxn],ifac[Maxn],pw[Maxn];//fac阶乘 ifac阶乘逆元
il int gi()
{
re int x=0;
re short int t=1;
re char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if(ch=='-') t=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*t;
}
int qp(int a,int x)
{
int ret=1;
for (;x;x>>=1,a=ll(a)*a%p)
if (x&1) ret=ll(ret)*a%p;
return ret;
}
int c(int n,int k)
{
return ll(fac[n])*ifac[k]%p*ifac[n-k]%p;
}
int main()
{
//freopen("allonsy.in", "r", stdin);
// freopen("allonsy.out", "w", stdout);
n=gi();q=gi();p=gi();
fac[0]=1;
fp(i,1,n)
fac[i]=ll(fac[i-1])*i%p;//预处理i的阶乘
ifac[n]=qp(fac[n],p-2);//ifac[i]=fac[i]的负一次方 在模P意义下同等于fac[N]的P-2次方 此即费马小定理
fq(i,n-1,0)
ifac[i]=ifac[i+1]*ll(i+1)%p;//预处理i的阶乘逆元
fp(i,0,n) pw[i]=1;
int q0=1,q1=1;
fp(i,1,n)
{
q0=q0*ll(q)%p;
q1=q1*ll(1+p-q)%p;
pw[i]=ll(pw[i])*q0%p;
pw[n-i]=ll(pw[n-i])*q1%p;
}
int ans=0;
fp(i,0,n)
ans=(ans+ll(c(n,i))*pw[i]%p*abs(2*i-n))%p;
//abs(2*i-n)为离原点距离
//c用于求组合数
printf("%d\n",ans);
return 0;
}

allonsy的更多相关文章

  1. THE BUG 队第一次团队作业

    1.队名: THE BUG 队 2.队员学号: 杨梓琦 3118005115(队长) 温海源,3118005109 陈杰才,3118005089 李华,3118005097 钟明康,311800512 ...

  2. THE BUG 队第一次团队项目作业

    队名: THE BUG 队 2.队员学号: 杨梓琦 3118005115(队长) 温海源,3118005109 陈杰才,3118005089 李华,3118005097 钟明康,3118005123 ...

随机推荐

  1. 第二节:SQLServer导出-重置sa密码-常用sql语句

    1.SQLServer导出: 点击要导出数据库----->右键(任务)----->生成脚本----->下一步----->下一步(高级)要编写脚本的数据类型---选择架构和数据 ...

  2. ocelot+consul+identity4的使用demo

    Ocelot网关搭建 搭建core控制台项目 本demo采用2.1版本 命名为APPIGateWay 在Nuget包中添加Ocelot引用 选用8.0.0版本 添加Ocelot.json 文件 内容为 ...

  3. crontab定时清理日志

    1.创建shell脚本 vi test_cron.sh #!/bin/bash#echo "====`date`====" >> /game/webapp/test_c ...

  4. JavaScript day1(注释)

    JavaScript中的注释方式有两种: 单行注释,使用 //. // This is an in-line comment. 多行注释,以/*开始,用*/来结束. /* This is a mult ...

  5. css--小白入门篇2

    一.css基础选择器 html负责结构,css负责样式,js负责行为. css写在head标签里面,容器style标签. 先写选择器,然后写大括号,大括号里面是样式. 1 <style type ...

  6. CentOS7 安装、配置 Memcached

    点击访问原文地址 介绍 Memcached 是一个分布式.高性能的内存缓存系统,通过缓存内存中的数据和对象,提高和加速动态 web 应用程序的性能.它主要用于加速对数据库重度使用的站点. Memcac ...

  7. Ubuntu notes

    ubuntu notes Table of Contents 1. backup data 2. Basics Ubuntu 3. Install, uninstall packages 4. Bas ...

  8. react入门-----(jsx语法,在react中获取真实的dom节点)

    1.jsx语法 var names = ['Alice', 'Emily', 'Kate']; <!-- HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的 ...

  9. 09.C语言:预处理(宏定义)、字节序、地址对齐

    一.预处理 预处理 gcc -E Hello.c -o hello.i 编译 gcc -S hello.i -o hello.s 汇编 gcc -c hello.s -o hello.o 链接 gcc ...

  10. 洛谷 2476 [SCOI2008]着色方案

    50%的数据满足:1 <= k <= 5, 1 <= ci <= 3 100%的数据满足:1 <= k <= 15, 1 <= ci <= 5 [题解] ...