Loading

Luogu10698 做题记录

link

我记得之前做过一道题也是这个东西,不过当时没有记录。

考虑 maxflow 实在是太难了,考虑 flow 实质上是边不相交的路径。

为了用上 LGV,考虑边转化为点,相邻的边之间随机附权,初始时 \(k\) 个起点向 \(1\) 的所有出边都连边且随机附权。

但这样连边数实在是太多了,考虑一个原图上一个点的出边,相当于是所有入边的向量的随机线性组合,可以求出所有入边的向量的线性基,然后出边就是线性基的随机线性组合。

对于一个点的答案,是其入边的向量组成的矩阵的秩,也就是该点的线性基大小,时间复杂度 \(\mathcal O(nk^2)\)。

不过我好想不太懂为什么答案是矩阵的秩。

点击查看代码
#include <bits/stdc++.h>
#define ll int
#define LL long long
#define fi first
#define se second
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
#define i128 __int128
#define uLL unsigned LL
#define For(i, a, b) for(ll i = a; i <= b; i++)
#define DFor(i, a, b) for(ll i = a; i >= b; i--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
template <class T1, class T2>
void chkmax(T1 &x, const T2 y) { x = x < y? y : x; }
template <class T1, class T2>
void chkmin(T1 &x, const T2 y) { x = x < y? x : y; }
template <class T>
void rd(T &x) {
    char ch; bool f = 0;
    while(!isdigit(ch = getchar()))
        if(ch == '-') f = 1;
    x = ch - '0';
    while(isdigit(ch = getchar()))
        x = (x << 1) + (x << 3) + ch - '0';
    if(f) x = -x;
}
const ll maxn = 1e5 + 10, mod = 998244353;
template <class T1, class T2>
void add(T1 &x, const T2 y) { x = x + y >= mod? x + y - mod : x + y; }
template <class T1, class T2>
void sub(T1 &x, const T2 y) { x = x < y? x + mod - y : x - y; }
ll power(ll a, ll b = mod - 2, ll p = mod) {
    ll s = 1;
    while(b) {
        if(b & 1) s = (LL) s * a % p;
        a = (LL) a * a % p, b >>= 1;
    } return s;
}
using namespace std;

ll n, m, k, h[maxn][55][55], q[maxn], l, r, deg[maxn];
vector <ll> to[maxn];
mt19937_64 rnd(20090623);

int main() {
    rd(n), rd(m), rd(k);
    For(i, 1, m) {
        ll u, v; rd(u), rd(v);
        to[u].pb(v), ++deg[v];
    }
    For(i, 1, k) h[1][i][i] = 1;
    l = 1, r = 0;
    For(i, 1, n)
        if(!deg[i]) q[++r] = i;
    while(l <= r) {
        ll u = q[l++];
        for(ll v: to[u]) {
            static ll d[55]; memset(d, 0, sizeof d);
            For(i, 1, k)
                if(h[u][i][i]) {
                    ll t = rnd() % mod;
                    For(j, i, k) add(d[j], (LL) h[u][i][j] * t %mod);
                }
            For(i, 1, k)
                if(d[i]) {
                    if(h[v][i][i]) {
                        ll t = (LL) d[i] * power(h[v][i][i]) %mod;
                        For(j, i, k)
                            sub(d[j], (LL) h[v][i][j] * t %mod);
                    } else {
                        For(j, i, k) h[v][i][j] = d[j];
                        break;
                    }
                }
            if(!--deg[v]) q[++r] = v;
        }
    }
    For(i, 2, n) {
        ll cnt = 0;
        For(j, 1, k) cnt += (h[i][j][j] > 0);
        printf("%d ", cnt);
    } puts("");
    return 0;
}
posted @ 2026-05-27 08:40  Sktn0089  阅读(49)  评论(0)    收藏  举报