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

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

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

      20250916

      T1

      街機游戲

      是最小鏈覆蓋,Dilworth 變成最長反鏈,斜著掃描線即可。

      代碼
      #include <iostream>
      #include <algorithm>
      #include <string.h>
      #define lowbit(x) ((x) & (-(x)))
      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, m;
      int t[500005], a[500005];
      pair<int, int> p[500005];
      int d[500005], dcnt;
      struct BIT {
          int bit[500005];
          void add(int x, int y) { for (++x; x; x -= lowbit(x)) bit[x] = max(bit[x], y); }
          int query(int x) {
              int ret = 0;
              for (++x; x <= 500001; x += lowbit(x)) ret = max(ret, bit[x]);
              return ret;
          }
      } bit;
      int f[500005];
      int main() {
          freopen("arcade.in", "r", stdin);
          freopen("arcade.out", "w", stdout);
          m = read(), n = read();
          for (int i = 1; i <= n; i++) t[i] = read();
          for (int i = 1, x, y; i <= n; i++) a[i] = read(), x = a[i], y = t[i], p[i].first = x + y, p[i].second = y - x, d[i] = y - x;
          sort(p + 1, p + n + 1);
          sort(d + 1, d + n + 1), dcnt = unique(d + 1, d + n + 1) - d - 1;
          int ans = 0;
          for (int i = 1; i <= n; i++) {
              int t = lower_bound(d + 1, d + dcnt + 1, p[i].second) - d;
              ans = max(ans, f[i] = bit.query(t + 1) + 1);
              bit.add(t, f[i]);
          }
          cout << ans << "\n";
          return 0;
      }
      

      T2

      01 完美序列

      做前綴和,欽定下邊界,只需要保證上邊界不要爆掉。要欽定下邊界 \(l\),就用不經過 \(l - 1\) 的方案減掉不經過 \(l\) 的方案。于是只需要求不經過 \(y = x + l\)\(y = x + r\)\((0, 0) \rightarrow (n, m)\) 路徑數量。反射容斥即可。

      代碼
      #include <iostream>
      #include <string.h>
      #define int long long
      using namespace std;
      const int P = 998244353;
      inline void Madd(int &x, int y) { (x += y) >= P ? (x -= P) : 0; }
      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, ifac[50000005];
      void Cpre(int n) {
          fac = ifac[0] = ifac[1] = 1;
          for (int i = 2; i <= n; i++) fac = 1ll * fac * i % P;
          ifac[n] = qpow(fac);
          for (int i = n - 1; i > 1; i--) ifac[i] = ifac[i + 1] * (i + 1ll) % P;
      }
      inline int C(int n, int m) { return (n < 0 || m < 0 || n < m) ? 0 : 1ll * fac * ifac[m] % P * ifac[n - m] % P; }
      int n, m, K;
      int ans;
      int calc(int l, int r) {
          if (l >= 0 || l >= m - n || r <= 0 || r <= m - n) return 0;
          int k = r - l, ans = 0;
          for (int t = -m / k; n - t * k + r >= 0; t++) {
              ans += C(n + m, n - t * k);
              if (ans >= P) ans -= P;
              ans += P - C(n + m, n - t * k + r);
              if (ans >= P) ans -= P;
          }
          return ans;
      }
      signed main() {
          freopen("irori.in", "r", stdin);
          freopen("irori.out", "w", stdout);
          cin >> n >> m >> K;
          Cpre(n + m);
          for (int l = -K; l <= 0; l++) {
              int r = l + K;
              Madd(ans, (P + calc(l - 1, r + 1) - (l == 0 ? 0 : calc(l, r + 1))) % P);
          }
          cout << ans << "\n";
          return 0;
      }
      

      T3

      單身狗的復仇

      視為二維點 \((i, p_i)\),由題目限制選擇的點的 \(p_i\) 必須隨 \(i\) 遞增。一個點可以從上一個點轉移來,當且僅當這兩點構成的矩形中沒有點。cdq 分治優化轉移即可。

      代碼
      #include <iostream>
      #include <algorithm>
      #include <string.h>
      #define lowbit(x) ((x) & (-(x)))
      #define int long long
      using namespace std;
      const int inf = 0x3f3f3f3f3f3f3f;
      int n;
      int p[200005], w[200005];
      int f[200005], stk[200005], sz;
      struct Segment_Tree {
          int mn[800005];
          void Set(int o, int l, int r, int x, int y) {
              if (l == r) return mn[o] = y, void();
              int mid = (l + r) >> 1;
              if (x <= mid) Set(o << 1, l, mid, x, y);
              else Set(o << 1 | 1, mid + 1, r, x, y);
              mn[o] = min(mn[o << 1], mn[o << 1 | 1]);
          }
          int Query(int o, int l, int r, int L, int R) {
              if (L <= l && r <= R) return mn[o];
              int mid = (l + r) >> 1;
              if (R <= mid) return Query(o << 1, l, mid, L, R);
              if (L > mid) return Query(o << 1 | 1, mid + 1, r, L, R);
              return min(Query(o << 1, l, mid, L, R), Query(o << 1 | 1, mid + 1, r, L, R));
          }
      } seg;
      int o[200005];
      struct BIT {
          int bit[200005];
          void Set(int x, int y) { for (; x <= n + 1; x += lowbit(x)) bit[x] = y; }
          int query(int x) {
              int ret = -1;
              for (; x; x -= lowbit(x)) ret = max(ret, bit[x]);
              return ret;
          }
      } bit;
      int _f(int x) {
          int l = 1, r = sz, mid, ret = sz + 1;
          while (l <= r) {
              mid = (l + r) >> 1;
              if (p[stk[mid]] > x) ret = mid, r = mid - 1;
              else l = mid + 1;
          }
          return ret;
      }
      void Solve(int l, int r) {
          if (l == r) return;
          int mid = (l + r) >> 1;
          Solve(l, mid); sz = 0;
          for (int i = l; i <= r; i++) o[i] = i;
          sort(o + l, o + r + 1, [](int x, int y) { return p[x] < p[y]; });
          int len = mid - l + 1;
          for (int i = l; i <= r; i++) {
              int x = o[i];
              if (x > mid) {
                  int y = bit.query(x);
                  int pos = _f(y);
                  f[x] = min(f[x], (pos == sz + 1 ? inf : seg.Query(1, 1, len, pos, sz)) + w[x]);
                  bit.Set(x, p[x]);
              } else {
                  while (sz && stk[sz] < x) --sz;
                  stk[++sz] = x; seg.Set(1, 1, len, sz, f[x]);
              }
          }
          for (int i = mid + 1; i <= r; i++) bit.Set(i, -1);
          Solve(mid + 1, r);
      }
      signed main() {
          freopen("revenge.in", "r", stdin);
          freopen("revenge.out", "w", stdout);
          memset(bit.bit, -1, sizeof bit.bit);
          memset(f, 63, sizeof f); f[0] = 0;
          cin >> n;
          for (int i = 1; i <= n; i++) cin >> p[i];
          p[n + 1] = n + 1;
          for (int i = 1; i <= n; i++) cin >> w[i];
          Solve(0, n + 1);
          cout << f[n + 1] << "\n";
          return 0;
      }
      

      T4

      毒性細菌

      一個細菌可以放多次,則可以想到每個放 \(2^i\) 個。每次 \(8\) 個一組,可以確定這里面有沒有 T。如果有 T,可以確定里面 S 的位置,并剩下一堆 R 和 T。否則需要再把這一組和一個 T 詢問來找出里面所有的 S。對于剩下的那堆 R 和 T,由于在每一組里面我們已經通過詢問確定了這里面存在 T,因此先把組內第一個 T 找到,利用掉這個信息,然后再把所有剩下的扔到一塊并每次取 \(8\) 個出來找到里面第一個 T。找 T 可以二分。由于每次二分詢問的東西很少,于是可以和前面的找 S 并行。然后就能過了。

      代碼
      #include "toxic.h"
      #include <iostream>
      #include <algorithm>
      #include <cassert>
      #include <vector>
      #include <random>
      using namespace std;
      random_device rd;
      mt19937 mtrand(rd());
      int o[305];
      vector<pair<int, int> > v1;
      vector<int> v2;
      vector<int> Q;
      int tox, c;
      void init(int l, int r, int t = 0) {
          Q.clear();
          for (int i = l; i <= r; i++) for (int j = 0; j < (1 << (i - l)); j++) Q.emplace_back(o[i]);
          if (t) Q.emplace_back(o[tox]);
      }
      char ans[315];
      bool chk(int l, int r, vector<int> &V = v2) {
          int t; Q.clear(); if (c != (int)v1.size()) init(v1[c].first, v1[c].second);
          for (int j = l; j <= r; j++) Q.emplace_back(o[V[j]]);
          if ((t = query_sample(Q)) == (int)Q.size()) {
              for (int j = l; j <= r; j++) ans[o[V[j]]] = 'R';
              return 0;
          } else {
              if (c != (int)v1.size()) { for (int j = 0; j < 8; j++) ans[o[v1[c].first + j]] = ((t & (1 << j)) ? 'S' : 'R'); ++c; }
              return 1;
          }
          assert(0);
          return 5148;
      }
      void determine_type(int n) {
          Q.clear(); v1.clear(), v2.clear(), tox = 0, c = 0;
          for (int i = 1; i <= n; i++) ans[i] = ' ', o[i] = i;
          shuffle(o + 1, o + n + 1, mtrand);
          for (int t, i = 1; i <= n; i += 8) {
              init(i, min(n, i + 7));
              if ((t = query_sample(Q)) != (int)Q.size()) {
                  vector<int> vt;
                  for (int j = 0; j < 8; j++) {
                      if (t & (1 << j)) ans[o[i + j]] = 'S';
                      else if (i + j <= n) vt.emplace_back(i + j);
                  }
                  int l = 0, r = (int)vt.size() - 1, mid;
                  while (l < r) {
                      mid = (l + r) >> 1;
                      if (chk(0, mid, vt)) r = mid;
                      else l = mid + 1;
                  }
                  for (int j = 0; j < l; j++) ans[o[vt[j]]] = 'R';
                  ans[o[tox = vt[l]]] = 'T';
                  for (int j = l + 1; j < (int)vt.size(); j++) v2.emplace_back(vt[j]);
              }
              else v1.emplace_back(i, min(n, i + 7));
          }
          int m = v2.size();
          for (int i = 0, t; i < m; i++) {
              Q.clear(); if (c != (int)v1.size()) init(v1[c].first, v1[c].second);
              for (int j = i; j < min(m, i + 8); j++) Q.emplace_back(o[v2[j]]);
              if ((t = query_sample(Q)) == (int)Q.size()) {
                  for (int j = i; j < min(m, i + 8); j++) ans[o[v2[j]]] = 'R';
                  i += 7;
              } else {
                  if (c != (int)v1.size()) { for (int j = 0; j < 8; j++) ans[o[v1[c].first + j]] = ((t & (1 << j)) ? 'S' : 'R'); ++c; }
                  int l = 0, r = min(7, m - i - 1), mid, tmp = -1;
                  while (l < r) {
                      mid = (l + r) >> 1;
                      if (chk(i, i + mid)) r = mid;
                      else l = mid + 1;
                  }
                  assert(l != -1);
                  ans[o[tox = v2[i = i + l]]] = 'T';
      
              }
          }
          if (c != (int)v1.size()) {
              for (int i = c; i < (int)v1.size(); i++) {
                  Q.clear(); init(v1[i].first, v1[i].second, 1);
                  int t = query_sample(Q);
                  for (int j = 0; j < 8; j++) ans[o[v1[i].first + j]] = ((t & (1 << j)) ? 'S' : 'R');
              }
          }
          for (int i = 1; i <= n; i++) answer_type(i, ans[i]);
      }
      

      反射容斥。

      交互題,考慮如何利用之前的詢問給出的信息。不能浪費。

      posted @ 2025-09-21 17:31  forgotmyhandle  閱讀(13)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品久久久久久无码国产| 精品久久精品久久精品九九| 色爱区综合激情五月激情| 日韩av一区二区三区精品| 国产91丝袜在线观看| 和黑人中出一区二区三区| 国产高颜值极品嫩模视频| 光山县| 99久久无色码中文字幕| 国产色无码专区在线观看 | 色欲国产精品一区成人精品| 亚洲精品成人一二三专区| 国产高清在线男人的天堂| 日本新janpanese乱熟| 亚洲人黑人一区二区三区| 九九热精品视频在线免费| 欧美日本在线一区二区三区| 西西人体大胆444WWW| 日韩老熟女av搜索结果| 4hu44四虎www在线影院麻豆| 无套后入极品美女少妇| 国产精品高清一区二区三区| 亚洲欧美日韩综合在线丁香| 亚洲日韩av无码一区二区三区人| 国产综合一区二区三区麻豆| 久久精品免视看国产成人| 国产色视频一区二区三区qq号| 中文无码热在线视频| 色综合久久综合久鬼色88| jlzz大jlzz大全免费| 久久天天躁狠狠躁夜夜2020老熟妇| 国产成人精品午夜二三区| 真实国产乱子伦视频| 国产AV影片麻豆精品传媒| 日韩一区二区三区在线观院| 久久精品一偷一偷国产| 人妻va精品va欧美va| 亚洲精品一区二区三区综合| 国产免费播放一区二区三区| 亚洲暴爽av天天爽日日碰| 人妻中文字幕精品系列|