心路历程

预计得分:$30 + 0 + 0 = 30$

实际得分:$0+0+0= 0$

T1算概率的时候没模爆long long了。。。

A

我敢打赌这不是noip难度。。。

考虑算一个位置的概率,若想要$k$步把它干掉,那么与他距离为$1$到$k - 1$的点都必须阻塞

且距离为$k$的点至少有一个没被阻塞

概率的处理可以用前缀和优化。

这样看似是$O(n^3 logn)$,但是却不能通过,考虑在前缀和处理的时候有很多没用的状态(超出边界)

加一些剪枝即可

#include<cstdio>
#define max(a, b) (a < b ? b : a)
#define LL long long
using namespace std;
const int MAXN = 201, mod = 1e9 + 7, INF = 1e9 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, M, a[MAXN][MAXN], g[MAXN][MAXN][MAXN], vis[MAXN][MAXN];
LL fastpow(LL a, LL p) {
    LL base = 1;
    while(p) {
        if(p & 1) base = 1ll * base * a % mod;
        a = 1ll * a * a % mod; p >>= 1;
    }
    return base;
}
LL inv(LL a) {
    return fastpow(a, mod - 2);
}
int mul(int a, int b) {
    if(1ll * a * b > mod) return 1ll * a * b % mod;
    else return a * b;
}
void Pre() {
    //cout << a[1][1] << endl;
    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= M; j++)
            g[0][i][j] = a[i][j] % mod;
 
    for(int k = 1; k <= max(N, M); k++)
        for(int i = 1; i <= N; i++)
            for(int j = 1; j <= M; j++) {
                if((i - k < 0) || (j - k < 0) || (i + k > N + 1) || (j + k > M + 1)) {vis[i][j] = 1; continue;}
                if(vis[i][j]) continue;
                g[k][i][j] = mul(g[k - 1][i - 1][j], g[k - 1][i + 1][j]);
                if(k > 2) g[k][i][j] = mul(g[k][i][j], inv(g[k - 2][i][j]));
                if(k >= 2) g[k][i][j] = mul(mul(g[k][i][j], inv(a[i][j + k - 2])), inv(a[i][j - k + 2]));
                g[k][i][j] = mul(mul(g[k][i][j], a[i][j + k]), a[i][j - k]);
            }
}
LL calc(int x, int y) {
    LL ans = 0, s = a[x][y];
    for(int i = 1; i <= max(N, M); i++) {
        if((x - i < 0) || (y - i < 0) || (x + i > N + 1) || (y + i > M + 1)) break;
        int now = g[i][x][y];
        ans = (ans + mul(mul(i, (1 - now + mod)), s)) % mod;
        s = mul(s, now);
    }
    return ans;
}
int main() {
//  freopen("a.in", "r", stdin);
    N = read(); M = read();
    for(LL i = 1; i <= N; i++) {
        for(LL j = 1; j <= M; j++) {
            LL x = read(), y = read();
            a[i][j] = mul(x, inv(y));
        }
    }
    Pre();
    for(LL i = 1; i <= N; i++, puts(""))
        for(LL j = 1; j <= M; j++)
            printf("%lld ", calc(i, j) % mod);
    return 0;
}
A

相关文章:

  • 2022-02-18
  • 2021-08-08
  • 2022-02-09
  • 2021-12-21
  • 2021-12-06
  • 2021-10-04
猜你喜欢
  • 2021-06-20
  • 2021-07-24
  • 2022-12-23
  • 2022-12-23
  • 2021-07-03
  • 2021-10-24
  • 2021-10-22
相关资源
相似解决方案