<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      20250915

      T1

      ZZH 的游戲

      二分答案之后,兩個點輪流跳到當前能跳到的最小點。如果沒法跳了且不都在 \(1\),那么無解。容易發(fā)現(xiàn)這是對的,可以通過建重構樹維護。然后發(fā)現(xiàn)二分答案不是必要的,只需要每次沒法跳的時候手動開大答案即可。復雜度瓶頸在建重構樹的并查集。

      代碼
      #include <iostream>
      #include <string.h>
      #include <vector>
      using namespace std;
      #define getchar() p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++
      char buf[1<<21], *p1, *p2, ch;
      long long read() {
          long long ret = 0, neg = 0; char c = getchar(); neg = (c == '-');
          while (c < '0' || c > '9') c = getchar(), neg |= (c == '-');
          while (c >= '0' && c <= '9') ret = ret * 10 + c - '0', c = getchar();
          return ret * (neg ? -1 : 1);
      }
      int n, s, t;
      vector<int> G1[1000005], G2[1000005];
      int f1[1000005], f2[1000005];
      int mn1[1000005], mn2[1000005];
      int dsu[1000005];
      int getf(int x) { return (dsu[x] == x ? x : (dsu[x] = getf(dsu[x]))); }
      int main() {
          freopen("game.in", "r", stdin);
          freopen("game.out", "w", stdout);
          int tc = read();
          while (tc--) {
              for (int i = 1; i <= n; i++) G1[i].clear(), G2[i].clear();
              n = read();
              for (int i = 1; i < n; i++) {
                  int u = read(), v = read();
                  G1[u].emplace_back(v);
                  G1[v].emplace_back(u);
              }
              for (int i = 1; i < n; i++) {
                  int u = read(), v = read();
                  G2[u].emplace_back(v);
                  G2[v].emplace_back(u);
              }
              for (int i = 1; i <= n; i++) {
                  dsu[i] = mn1[i] = i;
                  for (auto v : G1[i]) {
                      if (v < i) {
                          int y = getf(v);
                          dsu[y] = f1[y] = i, mn1[i] = min(mn1[i], mn1[y]);
                      }
                  }
              }
              for (int i = 1; i <= n; i++) {
                  dsu[i] = mn2[i] = i;
                  for (auto v : G2[i]) {
                      if (v < i) {
                          int y = getf(v);
                          dsu[y] = f2[y] = i, mn2[i] = min(mn2[i], mn2[y]);
                      }
                  }
              }
              cin >> s >> t;
              int ans = s + t;
              while (mn1[s] != 1 || mn2[t] != 1) {
                  while ((mn2[t] == 1 || mn1[s] + f2[t] > ans) && (mn1[s] == 1 || f1[s] + mn2[t] > ans)) ++ans;
                  while (1) {
                      bool c = 0;
                      while (mn1[s] != 1 && f1[s] + mn2[t] <= ans) s = f1[s], c = 1;
                      while (mn2[t] != 1 && mn1[s] + f2[t] <= ans) t = f2[t], c = 1;
                      if (!c) break;
                  }
              }
              cout << ans << "\n";
          }
          return 0;
      }
      

      T2

      環(huán)

      \(2p > n\) 的質數(shù)沒用,扔掉。接下來構造用到剩下所有東西的方案。

      把所有東西按照最小質因子分組。對于 \(12 \le 4p \le n\) 的質數(shù),通過 \(2p - p - \cdots - 4p\) 將它接進 \(2\) 里面。對于 \(3p \le n, 4p > n\) 的質數(shù),通過 \(2p_1 - 3p_1 - 3p_2 - 2p_2\) 把它們這樣接進來。由于指不定有奇數(shù)還是偶數(shù)個,最后結尾可能是 \(2\) 也可能是 \(3\)。只需要在后面接 \(6\) 并順帶把 \(3\) 那一組放進來即可。對于 \(n < 12\) 的情況容易特判。

      代碼
      #include <iostream>
      #include <string.h>
      #include <vector>
      using namespace std;
      int n, X, Y;
      vector<int> vec[500005], ans;
      vector<int> V;
      bool vis[500005], ip[500005], mark[500005];
      int main() {
          freopen("cycle.in", "r", stdin);
          freopen("cycle.out", "w", stdout);
          int tc;
          cin >> tc;
          while (tc--) {
              cin >> n;
              if (n >= 12) {
                  ans.clear(); V.clear();
                  for (int i = 2; i <= n; i++) vec[i].clear(), vis[i] = 0, mark[i] = 0;
                  for (int i = 2; i <= n; i++) {
                      if (mark[i]) continue;
                      ip[i] = 1;
                      if (i * 3 <= n && i * 4 > n) V.emplace_back(i);
                      for (int j = i; j <= n; j += i) if (!mark[j]) vec[i].emplace_back(j), mark[j] = 1;
                  }
                  auto ins = [&](int x) {
                      ans.emplace_back(x * 2);
                      for (auto v : vec[x]) if (!vis[v]) ans.emplace_back(v);
                      ans.emplace_back(x * 4);
                  };
                  if (V.size() & 1) V.emplace_back(-1);
                  // 2X - 3X - 3Y - 2Y
                  for (int i = 0; i < (int)V.size(); i += 2) {
                      X = V[i], Y = V[i + 1];
                      ans.emplace_back(2 * X), ans.emplace_back(X), ans.emplace_back(3 * X);
                      if (Y != -1) ans.emplace_back(3 * Y), ans.emplace_back(Y), ans.emplace_back(2 * Y);
                  }
                  for (auto v : ans) vis[v] = 1;
                  for (int i = 3; i <= n; i++) if (ip[i] && i * 4 <= n) ins(i);
                  for (auto v : ans) vis[v] = 1;
                  for (int i = 2; i <= n; i += 2) if (!vis[i]) ans.emplace_back(i);
                  cout << ans.size() << "\n";
                  for (auto v : ans) cout << v << " ";
              } else for (int i = (cout << n / 2 << "\n", 2); i <= n; i += 2) cout << i << " ";
              cout <<" \n";
          }
          return 0;
      }
      

      T3

      道路的眼淚

      路徑 \(\min\),想到重構樹。從大往小加點建出,則每個點的 \(V\) 集合即為其所有祖先。

      第一問:枚舉 LCA 容易計算答案。

      第二問:樹形 dp 即可。

      第三問:由于異或的優(yōu)秀性質,對于 \(\bigoplus V\) 中的每個點 \(x\),可以把 \(S\) 集合 \(\oplus \{ x, f_x \}\),其中 \(f_x\)\(x\) 在重構樹的祖先(沒有就算了),從而得到對應的 \(S\)。那么這樣我們就構造了 \(S\)\(V\) 的雙射。那么就做完了。

      代碼
      #include <iostream>
      #include <string.h>
      #include <vector>
      #define int long long
      using namespace std;
      #define getchar() p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++
      char buf[1<<21], *p1, *p2, ch;
      long long read() {
          long long ret = 0, neg = 0; char c = getchar(); neg = (c == '-');
          while (c < '0' || c > '9') c = getchar(), neg |= (c == '-');
          while (c >= '0' && c <= '9') ret = ret * 10 + c - '0', c = getchar();
          return ret * (neg ? -1 : 1);
      }
      const int P = 998244353;
      int n, m, K, ans;
      int pw[2000005];
      int h1[2000005], n1[4000005], t1[4000005], e1;
      int h2[2000005], n2[2000005], t2[2000005], e2;
      void add1(int u, int v) { t1[++e1] = v, n1[e1] = h1[u], h1[u] = e1; }
      void add2(int u, int v) { t2[++e2] = v, n2[e2] = h2[u], h2[u] = e2; }
      int qpow(int x, int y = P - 2) {
          int ret = 1;
          while (y) {
              if (y & 1) 
                  ret = ret * x % P;
              y >>= 1;
              x = x * x % P;
          }
          return ret;
      }
      int fac[2000005], ifac[2000005], inv[2000005];
      void Cpre(int n) {
          fac[0] = fac[1] = ifac[0] = ifac[1] = inv[0] = inv[1] = 1;
          for (int i = 2; i <= n; i++) {
              fac[i] = fac[i - 1] * i % P;
              inv[i] = (P - P / i) * inv[P % i] % P;
              ifac[i] = ifac[i - 1] * inv[i] % P;
          }
      }
      inline int C(int n, int m) { return (n < 0 || m < 0 || n < m) ? 0 : fac[n] * ifac[m] % P * ifac[n - m] % P; }
      int str;
      int sz[2000005];
      void dfs1(int x, int d) {
          sz[x] = 1;
          int s = 0;
          for (int i = h2[x]; i; i = n2[i]) {
              int v = t2[i];
              dfs1(v, d + 1);
              sz[x] += sz[v];
              s += P - pw[sz[v]] + 1;
          }
          s = (s + pw[sz[x]] - 1) % P;
          ans += s * qpow(d, K) % P;
      }
      int dp[2000005];
      void dfs2(int x) {
          dp[x] = 1;
          for (int i = h2[x]; i; i = n2[i]) {
              int v = t2[i];
              dfs2(v);
              dp[x] = dp[x] * dp[v] % P;
          }
          dp[x] = ((dp[x] - 1) * 2 * K + K + 1) % P;
      }
      int dsu[2000005];
      int getf(int x) { return (dsu[x] == x ? x : (dsu[x] = getf(dsu[x]))); }
      signed main() {
          Cpre(2000000);
          freopen("tearroad.in", "r", stdin);
          freopen("tearroad.out", "w", stdout);
          str = read(), n = read(), m = read(), K = read();
          pw[0] = 1;
          for (int i = 1; i <= n; i++) pw[i] = pw[i - 1] * 2 % P, dsu[i] = i;
          for (int i = 1; i <= m; i++) {
              int u = read(), v = read();
              add1(u, v);
              add1(v, u);
          }
          for (int i = n; i; i--) {
              for (int j = h1[i]; j; j = n1[j]) {
                  int v = t1[j];
                  if (v < i) continue;
                  if (getf(v) != getf(i)) add2(i, dsu[v]), dsu[dsu[v]] = i;
              }
          }
          if (str / 100) {
              dfs1(1, 1);
              cout << ans % P << " ";
          }
          if ((str / 10) & 1) {
              dfs2(1);
              cout << dp[1] - 1 << " ";
          }
          if (str & 1) {
              ans = 0;
              for (int i = 1; i <= n; i++) ans += C(n, i) * ((i + K - 1) / K) % P;
              cout << ans % P << "\n";
          }
          return 0;
      }
      

      T4

      田野

      離散化,之后的每個格點相當于一個矩形。顯然矩形只有四個角是重要的,對所有角跑最短路。

      第一問,對于詢問點求出在哪個矩形,四個方向過來取 \(\min\) 即可。

      第二問,相當于對每個矩形要求它每個時刻擴展了多少點。那么從四個角開始,分別考察每個角擴張的過程。對于某一個角,它一開始擴張的時候貢獻是 \(1\),之后每個時刻比前一個時刻的貢獻多 \(1\)。而之后它可能會撞到另外一個角,那么撞完了之后發(fā)現(xiàn)每個時刻比前一個時刻的貢獻增量就減少了 \(1\)。而之后它可能又要撞到另外一個角,那么撞完了之后每個時刻比前一個時刻的貢獻增量就又少了 \(1\)。而之后它可能就要撞到它對面的那個角了,那這么一撞就相當于強制停止這個角的貢獻了。于是我們只需要算出這個角分別什么時候撞到兩個鄰角,什么時候撞到對角,然后使用一些差分維護貢獻即可。當然這三個時間的相對順序也不是一定的,因此需要一些討論。由于范圍很大,需要將所有差分和詢問離線處理。

      總復雜度 \(\mathcal{O}(n^2\log n + q\log n)\)\(\mathcal{O}(n^2\log n + q\log (n^2 + q))\)。但也可能是類似的,反正就那樣。能過。

      代碼
      #include <iostream>
      #include <algorithm>
      #include <string.h>
      #include <vector>
      #include <queue>
      #include <array>
      #define int long long
      using namespace std;
      #define getchar() p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++
      char buf[1<<21], *p1, *p2, ch;
      long long read() {
          long long ret = 0, neg = 0; char c = getchar(); neg = (c == '-');
          while (c < '0' || c > '9') c = getchar(), neg |= (c == '-');
          while (c >= '0' && c <= '9') ret = ret * 10 + c - '0', c = getchar();
          return ret * (neg ? -1 : 1);
      }
      const int inf = 0x3f3f3f3f3f3f3f;
      int n, tp, q;
      int d_x[1005], dxcnt;
      int d_y[1005], dycnt;
      /*
      01
      23
      */
      struct node { int x, y, t, dis; };
      inline bool operator<(node x, node y) { return x.dis > y.dis; }
      priority_queue<node> Q;
      bool vis[1005][1005][4];
      int dist[1005][1005][4];
      int ban[1005][1005];
      void _dijkstra() {
          memset(dist, 63, sizeof dist);
          int sx = lower_bound(d_x + 1, d_x + dxcnt + 1, 0) - d_x;
          int sy = lower_bound(d_y + 1, d_y + dycnt + 1, 0) - d_y;
          Q.push((node) { sx, sy, 0, dist[sx][sy][0] = 0 });
          while (Q.size()) {
              node tmp = Q.top(); Q.pop();
              int x = tmp.x, y = tmp.y, t = tmp.t;
              if (vis[x][y][t]) continue;
              vis[x][y][t] = 1;
              auto chkupd = [&](int tx, int ty, int tt, int ww) {
                  if (!ban[tx][ty] && dist[tx][ty][tt] > dist[x][y][t] + ww) 
                      Q.push((node) { tx, ty, tt, dist[tx][ty][tt] = dist[x][y][t] + ww });
              };
              if (t == 0) {
                  if (x != 1) chkupd(x - 1, y, 1, 1);
                  if (y != dycnt - 1) chkupd(x, y + 1, 2, 1);
                  chkupd(x, y, 1, d_x[x + 1] - d_x[x] - 1);
                  chkupd(x, y, 2, d_y[y + 1] - d_y[y] - 1);
              } else if (t == 1) {
                  if (x != dxcnt - 1) chkupd(x + 1, y, 0, 1);
                  if (y != dycnt - 1) chkupd(x, y + 1, 3, 1);
                  chkupd(x, y, 0, d_x[x + 1] - d_x[x] - 1);
                  chkupd(x, y, 3, d_y[y + 1] - d_y[y] - 1);
              } else if (t == 2) {
                  if (x != 1) chkupd(x - 1, y, 3, 1);
                  if (y != 1) chkupd(x, y - 1, 0, 1);
                  chkupd(x, y, 3, d_x[x + 1] - d_x[x] - 1);
                  chkupd(x, y, 0, d_y[y + 1] - d_y[y] - 1);
              } else {
                  if (x != dxcnt - 1) chkupd(x + 1, y, 2, 1);
                  if (y != 1) chkupd(x, y - 1, 1, 1);
                  chkupd(x, y, 2, d_x[x + 1] - d_x[x] - 1);
                  chkupd(x, y, 1, d_y[y + 1] - d_y[y] - 1);
              }
          }
      }
      struct Node { int op, s, d, x; };
      vector<Node> vec;
      int ans[200005];
      inline int calc(int s, int d, int len) { int t = s + len * d; return (s * 2 + (len + 1) * d) * len / 2; }
      void work() {
          for (int i = 1; i < dxcnt; i++) {
              for (int j = 1; j < dycnt; j++) {
                  if (ban[i][j]) continue;
                  int X = d_x[i + 1] - d_x[i], Y = d_y[j + 1] - d_y[j], t;
                  if (X == Y && Y == 1) vec.push_back({ 1, 1, 0, dist[i][j][0] }), vec.push_back({ -1, 1, 0, dist[i][j][0] + 1 });
                  else for (int k : { 0, 1, 2, 3 }) {
                      t = Y - 2 - abs(dist[i][j][k] - dist[i][j][k ^ 2]);
                      int t1 = (t >> 1) + (t & 1) * (k < (k ^ 2)) + max(dist[i][j][k], dist[i][j][k ^ 2]);
                      t = X - 2 - abs(dist[i][j][k] - dist[i][j][k ^ 1]);
                      int t2 = (t >> 1) + (t & 1) * (k < (k ^ 1)) + max(dist[i][j][k], dist[i][j][k ^ 1]);
                      t = X + Y - 3 - abs(dist[i][j][k] - dist[i][j][k ^ 3]);
                      int t3 = (t >> 1) + (t & 1) * (k < (k ^ 3)) + max(dist[i][j][k], dist[i][j][k ^ 3]);
                      if (t1 < dist[i][j][k] || t2 < dist[i][j][k]) continue;
                      (t1 > t2) ? swap(t1, t2) : void();
                      vec.push_back({ 1, 1, 1, dist[i][j][k] });
                      if (t3 < t1) {
                          vec.push_back({ -1, t3 + 2 - dist[i][j][k], -1, t3 + 1 });
                          continue;
                      }
                      vec.push_back({ -1, t1 + 2 - dist[i][j][k], -1, t1 + 1 });
                      vec.push_back({ 1, t1 + 1 - dist[i][j][k], 0, t1 + 1 });
                      if (t3 < t2) {
                          vec.push_back({ -1, t1 + 1 - dist[i][j][k], 0, t3 + 1 });
                          continue;
                      }
                      vec.push_back({ -1, t1 + 1 - dist[i][j][k], 0, t2 + 1 });
                      vec.push_back({ 1, t1 - dist[i][j][k], -1, t2 + 1 });
                      vec.push_back({ -1, max(0ll, t1 - dist[i][j][k] - (t3 - t2)), 1, min(t3 + 1, t2 + 1 + t1 - dist[i][j][k]) });
                  }
              }
          }
          sort(vec.begin(), vec.end(), [](Node x, Node y) { return x.x == y.x ? (abs(x.op) > abs(y.op)) : (x.x < y.x); });
          int dd = 0, al = 0, k = 0, lst = 0;
          for (auto v : vec) {
              dd += calc(al, k, v.x - lst); al += k * (v.x - lst); lst = v.x;
              if (v.op == 0) ans[v.d] = dd;
              else if (v.op == 1) al += v.s, k += v.d, dd += v.s;
              else al -= v.s, k += v.d, dd -= v.s;
          }
      }
      array<int, 4> rect[405];
      signed main() {
          freopen("field.in", "r", stdin);
          freopen("field.out", "w", stdout);
          n = read(), tp = read(), q = read();
          for (int i = 1; i <= n; i++) {
              int &x1 = rect[i][0], &x2 = rect[i][1], &y1 = rect[i][2], &y2 = rect[i][3];
              x1 = read(), x2 = read(), y1 = read(), y2 = read();
              d_x[++dxcnt] = x1, d_x[++dxcnt] = x2 + 1;
              d_y[++dycnt] = y1, d_y[++dycnt] = y2 + 1;
          }
          d_x[++dxcnt] = 0, d_x[++dxcnt] = 1;
          d_x[++dxcnt] = -inf, d_x[++dxcnt] = inf;
          d_y[++dycnt] = 0, d_y[++dycnt] = 1;
          d_y[++dycnt] = -inf, d_y[++dycnt] = inf;
          sort(d_x + 1, d_x + dxcnt + 1); dxcnt = unique(d_x + 1, d_x + dxcnt + 1) - d_x - 1;
          sort(d_y + 1, d_y + dycnt + 1); dycnt = unique(d_y + 1, d_y + dycnt + 1) - d_y - 1;
          for (int i = 1; i <= n; i++) {
              int x1, x2, y1, y2;
              x1 = lower_bound(d_x + 1, d_x + dxcnt + 1, rect[i][0]) - d_x;
              x2 = lower_bound(d_x + 1, d_x + dxcnt + 1, rect[i][1] + 1) - d_x;
              y1 = lower_bound(d_y + 1, d_y + dycnt + 1, rect[i][2]) - d_y;
              y2 = lower_bound(d_y + 1, d_y + dycnt + 1, rect[i][3] + 1) - d_y;
              ++ban[x1][y1], --ban[x2][y1], --ban[x1][y2], ++ban[x2][y2];
          }
          for (int i = 1; i <= dxcnt; i++) {
              for (int j = 1; j <= dycnt; j++) 
                  ban[i][j] += ban[i - 1][j] + ban[i][j - 1] - ban[i - 1][j - 1];
          }
          _dijkstra();
          if (tp == 1) {
              while (q--) {
                  int x = read(), y = read(), tx, ty, ans;
                  tx = upper_bound(d_x + 1, d_x + dxcnt + 1, x) - d_x - 1;
                  ty = upper_bound(d_y + 1, d_y + dycnt + 1, y) - d_y - 1;
                  ans = min({ 
                      dist[tx][ty][0] + x - d_x[tx] + d_y[ty + 1] - y - 1, 
                      dist[tx][ty][1] + d_x[tx + 1] - x - 1 + d_y[ty + 1] - y - 1, 
                      dist[tx][ty][2] + x - d_x[tx] + y - d_y[ty], 
                      dist[tx][ty][3] + d_x[tx + 1] - x - 1 + y - d_y[ty]
                  });
                  cout << (ans >= inf ? -1 : ans) << "\n";
              }
          } else {
              for (int i = 1; i <= q; i++) vec.push_back({ 0, 0, i, read() }); work();
              for (int i = 1; i <= q; i++) cout << ans[i] << "\n";
          }
          return 0;
      }
      

      T1。

      T3,構造雙射以計數(shù)。樹形 dp。

      T4。對每個矩形分開考慮每個角獨立的貢獻。

      posted @ 2025-09-16 23:10  forgotmyhandle  閱讀(11)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日本高清视频网站www| 色一情一乱一区二区三区码| 国产高清av首播原创麻豆| 国产三级精品三级在线看| 亚洲人成色99999在线观看 | 亚洲国产精品日韩AV专区| 91老肥熟女九色老女人| 在线 | 国产精品99传媒a| 国产蜜臀视频一区二区三区| 国内精品久久久久影院网站| 亚洲成av人片无码天堂下载| 国产一区二区三区精品综合| 精品久久久久久成人AV| 久热色视频精品在线观看| 亚洲欧美人成电影在线观看| 57pao成人国产永久免费视频| 日本夜爽爽一区二区三区| 精品国产欧美一区二区三区在线| 国产精品成人国产乱| 韩国精品福利视频一区二区| 午夜DY888国产精品影院 | 日韩一区二区三区水蜜桃| 国产av普通话对白国语| 久久一区二区中文字幕| 干老熟女干老穴干老女人| √天堂资源地址在线官网| 亚洲高清激情一区二区三区| 99久久精品国产一区二区蜜芽| 成人年无码av片在线观看| 日韩深夜福利视频在线观看| 97夜夜澡人人爽人人模人人喊| 久青草精品视频在线观看| 精品无码一区二区三区爱欲| 亚洲中文字幕无码av永久| 午夜精品一区二区三区免费视频| 亚洲天堂领先自拍视频网| 承德市| 亚洲成人av在线资源网| 国内精品久久久久影院日本| 中文字幕理伦午夜福利片| 国产av剧情md精品麻豆|