Submission #1197391

#TimeUsernameProblemLanguageResultExecution timeMemory
1197391sleepntsheep한자 끝말잇기 (JOI14_kanji)C11
100 / 100
101 ms10312 KiB
#include "Annalib.h"
#include <stdio.h>
#include <string.h>

#define N 300
#define Q 60
#define K 5

void Anna(int n, int m, int a[], int b[], long long c[], int q, int s[], int t[], int k, int u[]) {
  static long long dp[N][N];
  unsigned long long message;
  static int ii[Q], ii_[Q], brk[K], ll[K + 1], rr[K + 1], rr_[K], ll_[K], ban[999999];
  /* since we are forced to do this process forward (0-k),
   * but multiplying directly to message will reverse the order of messages sent, (stack-like)
   * Anna need to add breakpoints to message one by one, backward ordered */ 
  int gap[15], at[15], sz;
  sz = 0;

  memset(ban, 0, sizeof ban);
  for (int i = 0; i < k; ++i)
    ban[u[i]] = 1;
  message = 0;

  memset(dp, 0x3f, sizeof dp);
  for (int i = 0; i < n; ++i) dp[i][i] = 0;
  for (int i = 0; i < m; ++i) if (! ban[i]) dp[a[i]][b[i]] = c[i];
  for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j)
    if (dp[i][k] + dp[k][j] < dp[i][j])
      dp[i][j] = dp[i][k] + dp[k][j];

  for (int i = 0; i < q; ++i) ii[i] = i;
  ll[0] = 0;
  rr[0] = q;

  /*https://www.luogu.com.cn/problem/solution/AT_joisc2014_l*/
  for (int p = 1; p <= k; ++p) {
    for (int i_ = 0; i_ < p; ++i_)
      for (int it = ll[i_]; it < rr[i_]; ++it)
        for (int j = ll[i_] + 1; j < rr[i_]; ++j)
          if (p == k) {
            if (dp[s[ii[j - 1]]][t[ii[j - 1]]] - (dp[b[u[i_]]][t[ii[j - 1]]] + dp[s[ii[j - 1]]][a[u[i_]]]) < 
              dp[s[ii[j]]][t[ii[j]]] - (dp[b[u[i_]]][t[ii[j]]] + dp[s[ii[j]]][a[u[i_]]]))
              ii[j - 1] ^= ii[j], ii[j] ^= ii[j - 1], ii[j - 1] ^= ii[j];
          } else {
            for (int j = ll[i_] + 1; j < rr[i_]; ++j)
              if (dp[b[u[i_]]][t[ii[j - 1]]] - dp[b[u[p]]][t[ii[j - 1]]] > dp[b[u[i_]]][t[ii[j]]] - dp[b[u[p]]][t[ii[j]]])
                ii[j - 1] ^= ii[j], ii[j] ^= ii[j - 1], ii[j - 1] ^= ii[j];
          }

    for (int i_ = 0; i_ < p; ++i_) {
      brk[i_] = rr[i_];
      /* since sorted by f1 - f2, we can find the breakpoint (suffix) of each interval */ 
      brk[i_] = rr[i_];
      if (p < k) {
        for (int j = rr[i_] - 1; j >= ll[i_]; --j)
          /* lhs is constant, rhs is sorted */
          if (c[u[p]] - c[u[i_]] <= dp[b[u[i_]]][t[ii[j]]] - dp[b[u[p]]][t[ii[j]]])
            /* beneficial to switch to new group */
            brk[i_] = j;
          else
            break;
      } else {
        for (int j = rr[i_] - 1; j >= ll[i_]; --j) {
          if (dp[s[ii[j]]][t[ii[j]]] - (dp[s[ii[j]]][a[u[i_]]] + dp[b[u[i_]]][t[ii[j]]]) < c[u[i_]])
            brk[i_] = j;
          else
            break;
        }
      }

      gap[sz] = rr[i_] - ll[i_] + 1;
      at[sz] = brk[i_] - ll[i_];
      ++sz;
    }

    int qwq = 0;
    for (int i_ = 0; i_ < p; ++i_) {
      ll_[i_] = ll[i_];
      ll[i_] = qwq;
      for (int j = ll_[i_]; j < brk[i_]; ++j)
        ii_[qwq++] = ii[j];
      rr_[i_] = rr[i_];
      rr[i_] = qwq;
    }
    ll[p] = qwq;
    for (int i_ = 0; i_ < p; ++i_)
      for (int j = brk[i_]; j < rr_[i_]; ++j)
        ii_[qwq++] = ii[j];
    rr[p] = qwq;

    memcpy(ii, ii_, sizeof ii);
  }

  while (sz)
    --sz, message = message * gap[sz] + at[sz];

  for (int i = 0; i < 64; ++i)
    Tap(message & 1), message >>= 1;
}

#include "Brunolib.h"
#include <stdio.h>
#include <string.h>

#define N 300
#define Q 60
#define K 5

void PATH(int bt[N][N], int id[N][N], int s, int t) {
  if (s == t)
    return;
  if (bt[s][t] == -1) {
    Answer(id[s][t]);
    return;
  }
  PATH(bt, id, s, bt[s][t]);
  PATH(bt, id, bt[s][t], t);
}

void Bruno(int n, int m, int a[], int b[], long long c[], int q, int s[], int t[], int k, int u[], int l, int x[]) {
  static long long dp[N][N]/* shortest path with backtrack */;
  static int bt[N][N], id[N][N];
  static int ii[Q], ii_[Q], brk[K], ll[K + 1], rr[K + 1], rr_[K], ll_[K], group_[Q];
  unsigned long long message;

  message = 0;
  for (int i = 63; i >= 0; --i)
    message = (message << 1) | x[i];

  memset(bt, -1, sizeof bt);
  memset(dp, 0x3f, sizeof dp);
  for (int i = 0; i < n; ++i) dp[i][i] = 0;
  for (int i = 0; i < m; ++i) if (~ c[i]) dp[a[i]][b[i]] = c[i], id[a[i]][b[i]] = i;
  for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j)
    if (dp[i][k] + dp[k][j] < dp[i][j])
      dp[i][j] = dp[i][k] + dp[k][j], bt[i][j] = k;

  for (int i = 0; i < q; ++i) ii[i] = i;
  ll[0] = 0;
  rr[0] = q;

  /*https://www.luogu.com.cn/problem/solution/AT_joisc2014_l*/
  for (int p = 1; p <= k; ++p) {
    for (int i_ = 0; i_ < p; ++i_)
      for (int it = ll[i_]; it < rr[i_]; ++it)
        for (int j = ll[i_] + 1; j < rr[i_]; ++j)
          if (p == k) {
            if (dp[s[ii[j - 1]]][t[ii[j - 1]]] - (dp[b[u[i_]]][t[ii[j - 1]]] + dp[s[ii[j - 1]]][a[u[i_]]]) < 
              dp[s[ii[j]]][t[ii[j]]] - (dp[b[u[i_]]][t[ii[j]]] + dp[s[ii[j]]][a[u[i_]]]))
              ii[j - 1] ^= ii[j], ii[j] ^= ii[j - 1], ii[j - 1] ^= ii[j];
          } else {
            for (int j = ll[i_] + 1; j < rr[i_]; ++j)
              if (dp[b[u[i_]]][t[ii[j - 1]]] - dp[b[u[p]]][t[ii[j - 1]]] > dp[b[u[i_]]][t[ii[j]]] - dp[b[u[p]]][t[ii[j]]])
                ii[j - 1] ^= ii[j], ii[j] ^= ii[j - 1], ii[j - 1] ^= ii[j];
          }

    for (int i_ = 0; i_ < p; ++i_) {
      brk[i_] = message % (rr[i_] - ll[i_] + 1) + ll[i_];
      message /= rr[i_] - ll[i_] + 1;
    }

    /* move stuff */
    int qwq = 0;
    for (int i_ = 0; i_ < p; ++i_) {
      ll_[i_] = ll[i_];
      ll[i_] = qwq;
      for (int j = ll_[i_]; j < brk[i_]; ++j)
        ii_[qwq++] = ii[j];
      rr_[i_] = rr[i_];
      rr[i_] = qwq;
    }
    ll[p] = qwq;
    for (int i_ = 0; i_ < p; ++i_)
      for (int j = brk[i_]; j < rr_[i_]; ++j)
        ii_[qwq++] = ii[j];
    rr[p] = qwq;

    memcpy(ii, ii_, sizeof ii);
  }

  for (int i = 0; i <= k; ++i)
    for(int j = ll[i]; j < rr[i]; ++j)
      group_[ii[j]] = i;


  /* we got all needed information to answer queries, now backtracking pain */
  for (int group, i = 0; i < q; ++i) {
    group = group_[i];

    if (k == group)
      PATH(bt, id, s[i], t[i]);
    else {
      PATH(bt, id, s[i], a[u[group]]);
      Answer(u[group]);
      PATH(bt, id, b[u[group]], t[i]);
    }

    Answer(-1);
  }

}


#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...