JZOJ 5616. 【NOI2018模拟3.31】沧海尘记

11 篇文章 0 订阅
3 篇文章 0 订阅

Description

Description

Input

Input

Output

Output

Data Constraint

Data Constraint

Solution

  • 观察题目,就可以得出有变换:

    Ai=j=1nAjPi,j

  • 那么用 O(N3) 的高斯消元就可以通过 52% 的数据。

  • 要 AC 此题,就要用到 MCMC(Markov Chain-Monte Carlo,⻢尔科夫链蒙特卡洛)算法

  • 天啊!什么高大上的算法?

  • 随机得出⼀个概率向量 A ,计算 APk,输出即可。

  • 其实就是随意使某个位置为 1 (例如使 A1=1),其它位置为 0

  • 之后不断执行 O(N2) 的变换, A 始终会变成所求的行向量(别问我为什么)。

  • 要使用这个MCMC算法呢,就要什么变换需没周期性、不可约,具体可参考zhiyong_will的博客

  • 具体实现的时候可以写⼀个 while 循环,直到

    Maxni=1|AiBi|<1015

  • ⼀般来说 kmax=12 ,则时间复杂度 O(kN2)

Code

#include<cstdio>
#include<cmath>
#include<cctype>
using namespace std;
typedef double DB;
const int N=2505;
const DB eps=1e-15;
int n,a,b,c;
int q[N];
DB p[N][N],f[N],g[N];
int main()
{
    scanf("%d%d%d%d",&n,&a,&b,&c);
    for(int i=1;i<=n;i++)
    {
        int s=q[1]=(a*q[n]+b)%c;
        for(int j=2;j<=n;j++) s+=q[j]=(a*q[j-1]+b)%c;
        s+=n;
        for(int j=1;j<=n;j++) p[i][j]=((DB)q[j]+1)/s;
    }
    f[1]=1;
    while(true)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) g[j]+=f[i]*p[i][j];
        bool pd=true;
        for(int i=1;i<=n;i++)
            if(fabs(f[i]-g[i])>eps)
            {
                pd=false;
                break;
            }
        if(pd) break;
        for(int i=1;i<=n;i++) f[i]=g[i],g[i]=0;
    }
    for(int i=1;i<=n;i++) printf("%.18lf ",g[i]);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值