社区讨论

40分求助(后6点全输出0,不知道是被卡精度还是写挂了)

P3706[SDOI2017] 硬币游戏参与者 1已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lo330gwb
此快照首次捕获于
2023/10/23 23:58
2 年前
此快照最后确认于
2023/10/23 23:58
2 年前
查看原帖
CPP
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double db;

const int maxn = 1000;
const ull P = 2333;
const db eps = 1e-8;

ll R()
{
    ll x = 0,f = 1;
    char c = getchar();
    while(c > '9' || c < '0')
    {
        if(c == '-')f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9')
    {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }
    return x * f;
}

db a[maxn][maxn],p[maxn],ans[maxn];
char s[maxn];
ull pre[maxn][maxn],suf[maxn][maxn],ha[maxn];

void init(ll m)
{
    ha[0] = 1,p[0] = 1;
    for(int i = 1 ; i <= m ; i++)ha[i] = ha[i-1] * P;
    for(int i = 1 ; i <= m ; i++)p[i] = p[i-1] * (db)0.5;
}

void guass(ll n)
{
    ll heng = 1;
    for(int i = 1 ; i <= n ; i++)
    {
        ll mx = heng;
        for(int j = heng + 1 ; j <= n ; j++)if(fabs(a[j][i]) - fabs(a[mx][i]) > eps)mx = j;
        if(fabs(a[mx][i]) < eps)continue;
        for(int j = 1 ; j <= n + 1 ; j++)swap(a[heng][j],a[mx][j]);
        for(int j = 1 ; j <= n ; j++)
        {
            if(heng == j)continue;
            db t = a[j][i] / a[heng][i];
            for(int k = 1 ; k <= n + 1 ; k++)a[j][k] -= a[heng][k] * t;
        }
        heng++;
    }
}

void Lei()
{
    ll n = R(),m = R();
    init(m);
    for(int i = 1 ; i <= n ; i++)
    {
        scanf("%s",s+1);
        for(int j = 1 ; j <= m ; j++)
        {
            pre[i][j] = pre[i][j-1] * P + (ull)s[j];
            suf[i][j] = ha[j-1] * (ull)s[m-j+1] + suf[i][j-1];
        }
    }
    for(int i = 1 ; i <= n ; i++)
    {
        a[i][n+1] = -p[m],a[n+1][i] = (db)1.0;
        for(int j = 1 ; j <= n ; j++)
            for(int k = 1 ; k <= m ; k++)
                if(pre[i][k] == suf[j][k])a[i][j] += p[m-k];
    }
    a[n+1][n+2] = (db)1.0;
    guass(n+1);
    for(int i = 1 ; i <= n ; i++)ans[i] = a[i][n+2] / a[i][i];
    for(int i = 1 ; i <= n ; i++)printf("%.10lf\n",ans[i]);
}

int main()
{
    Lei();
    return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...