1 条题解

  • 0
    @ 2025-8-24 22:20:15

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 一扶苏一
    休息结束。邮箱 yifusuyi@qq.com

    搬运于2025-08-24 22:20:15,当前版本为作者最后更新于2020-04-15 20:08:42,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    【dp】【P6381】『MdOI R2』Odyssey

    Analysis

    这里有一个比较暴力不需要分析性质的做法。

    首先对 ww 分解质因数并把指数对 kk 取模,把结果 hash 一下,并记录与其配对的数字的 hash 值。然后套路的进行 DAG 上 dp,用 map 存一下状态即可。

    fu,if_{u, i} 是以 uu 为起点,第一条边的 hash 值为 ii 的最长路,转移为

    fu,i=max{fv,pi+l}f_{u, i} = \max\{f_{v, pi} + l\}

    其中 pipi 是与 ii 配对的 hash 值,vv 是从 uu 出发的 hash 为 ii 的边指向的所有节点,ll 是对应边的长度。

    时间复杂度 O(mlogw+mlogm+w)O(m \log w + m \log m + w)

    Code

    写起来有点码农,为了防止被卡用了双模数 hash。

    namespace Fusu {
    
    const int maxn = 200005;
    const int INF = 2000000005;
    
    void Init();
    void Calc();
    void GetPrime();
    void Topo_sort();
    void Make_hash();
    
    void Main() {
      Init();
      GetPrime();
      Topo_sort();
      Make_hash();
      Calc();
    }
    
    int n, m, t;
    int ind[maxn];
    struct Edge {
      int v, w, l, nxt;
    };
    Edge edge[maxn];
    int hd[maxn];
    int ecnt;
    inline void cont(const int u, const int v, const int w, const int l) {
      auto &e = edge[++ecnt];
      e.v = v; e.w = w; e.l = l; e.nxt = hd[u];
      hd[u] = ecnt;
    }
    
    void Init() {
      qr(n); qr(m); qr(t);
      for (int i = 1, u, v, w, l; i <= m; ++i) {
        qr(u); qr(v); qr(w); qr(l);
        cont(u, v, w, l);
        ++ind[v];
      }
    }
    
    std::queue<int> Q;
    int top;
    int topo[maxn];
    void Topo_sort() {
      for (int i = 1; i <= n; ++i) if (ind[i] == 0) {
        Q.push(i);
      }
      for (int u, v; !Q.empty(); Q.pop()) {
        topo[++top] = u = Q.front();
        for (int e = hd[u]; e; e = edge[e].nxt) if (--ind[v = edge[e].v] == 0) {
          Q.push(v);
        }
      }
    }
    
    int pcnt;
    int prm[maxn], pre[maxn];
    bool np[maxn];
    void GetPrime() {
      const int x = 100000;
      for (int i = 2; i <= x; ++i) {
        if (np[i] == false) {
          prm[++pcnt] = i;
          pre[i] = pcnt;
        }
        for (int j = 1, k = prm[j] * i; j <= pcnt; k = prm[++j] * i) if (k <= x) {
          np[k] = true;
          pre[k] = j;
          if ((i % prm[j]) == 0) break;
        } else {
          break;
        }
      }
    }
    
    const int maxh = 2;
    const int pmod[] = {998244353, 1000000009};
    
    int dcnt;
    std::vector<int> d, cd;
    int make_hash(const int x) {
      ll ret = 0;
      for (int i = 0; i < dcnt; ++i) if (cd[i] != 0) {
        (ret += (d[i] ^ 20020924ll) * (cd[i] ^ 20020301ll)) %= pmod[x];
      }
      return ret;
    }
    
    int hash[maxh][maxn], ph[maxh][maxn];
    void Make_hash() {
      for (int i = 1; i <= m; ++i) {
        d.clear(); cd.clear(); dcnt = 0;
        for (int x = edge[i].w, pp = 0; x != 1; x /= prm[pre[x]]) if (pp == pre[x]) {
          if (++cd[dcnt - 1] == t) cd[dcnt - 1] = 0;
        } else {
          d.push_back(pre[x]);
          cd.push_back(t != 1);
          ++dcnt;
          pp = pre[x];
        }
        for (int j = 0; j < maxh; ++j) {
          hash[j][i] = make_hash(j);
        }
        for (int j = 0; j < dcnt; ++j) if (cd[j]) {
          cd[j] = t - cd[j];
        }
        for (int j = 0; j < maxh; ++j) {
          ph[j][i] = make_hash(j);
        }
      }
    }
    
    std::map<std::pair<int, int>, int> f[maxn];
    void Calc() {
      std::pair<int, int> k;
      int ans = 0;
      for (int i = n, u = topo[i], v; i; u = topo[--i]) {
        for (int e = hd[u]; e; e = edge[e].nxt) {
          v = edge[e].v;
          k = std::make_pair(hash[0][e], hash[1][e]);
          f[u][k] = std::max(f[u][k], edge[e].l);
          auto j = std::make_pair(ph[0][e], ph[1][e]);
          f[u][k] = std::max(f[u][k], edge[e].l + f[v][j]);
          ans = std::max(ans, f[u][k]);
        }
      }
      qw(ans, '\n');
    }
    
    } // namespace Fusu
    
    • 1

    信息

    ID
    5162
    时间
    1000ms
    内存
    500MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者