牛客挑战赛39题解

屑挑战赛

真心无聊。。div1难度能轻松口胡.jpg

A,随便二分一下就没了,或者排个序啥的,无所谓…

B,后缀排序套个板子就过了…

C,线段树上面乱搞,他说了模数你乘起来发现不超过 int,随便写就过了…

D,子集卷积完了 NTT,然后 FWT 一手就过了。

E,随便 DP 一下就过了。

F,二合一的题,cot2+bzoj原题搬到序列上,随便写即可,这种做法应该是吊打 std 了…还是我应该说 std 太蠢了…

代码到时候再补…

A.

#include <bits/stdc++.h>
#define in cin
using namespace std;

signed main() {
  ios ::sync_with_stdio(false);
  cin.tie(nullptr), cout.tie(nullptr);
  int _;
  in >> _;
  while (_--) {
    int n;
    in >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) in >> a[i];
    vector<int> l, r;
    l.push_back(0), r.push_back(0);
    for (int i = 0; i < n; i++) {
      if (a[i] < 0) {
        l.push_back(-a[i]);
      } else {
        r.push_back(a[i]);
      }
    }
    sort(l.begin(), l.end());
    sort(r.begin(), r.end());
    int ans = 1e9, res = 1e9;
    for (int i = 0; i < r.size() - 1; i++) {
      int x = r[i + 1] + r.back() >> 1;
      res = min(res, max({ r[i], x - r[i + 1], r.back() - x }));
    }
    ans = min(ans, max(res, l.back()));
    res = 1e9;
    for (int i = 0; i < l.size() - 1; i++) {
      int x = l[i + 1] + l.back() >> 1;
      res = min(res, max({ l[i], x - l[i + 1], l.back() - x }));
    }
    ans = min(ans, max(res, r.back()));
    cout << ans << '\n';
  }
  return 0;
}

B.

#include <bits/stdc++.h>
using namespace std;
int n, K;
const int maxn = 1e6 + 61;
char s[maxn];
signed main() {
  ios ::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  cin >> n >> K;
  cin >> s + 1;
  for (int i = 1; i <= K; i++) s[i + n] = s[i];
  n += K;
  static int x[maxn], y[maxn], c[maxn], sa[maxn];
  for (int i = 1; i <= n; i++) ++c[x[i] = s[i]];
  int m = 122;
  for (int i = 1; i <= m; i++) c[i] += c[i - 1];
  for (int i = n; i; i--) sa[c[x[i]]--] = i;
  for (int k = 1; k <= n; k <<= 1) {
    int p = 0;
    for (int i = 0; i <= m; i++) y[i] = 0;
    for (int i = n - k + 1; i <= n; i++) y[++p] = i;
    for (int i = 1; i <= n; i++)
      if (sa[i] > k) y[++p] = sa[i] - k;
    for (int i = 0; i <= m; i++) c[i] = 0;
    for (int i = 1; i <= n; i++) ++c[x[y[i]]];
    for (int i = 1; i <= m; i++) c[i] += c[i - 1];
    for (int i = n; i; i--) sa[c[x[y[i]]]--] = y[i];
    swap(x, y);
    x[sa[1]] = p = 1;
    for (int i = 2; i <= n; i++)
      x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) ? p : ++p;
    if (p >= n) break;
    m = p;
  }

  static int cnt[maxn];
  for (int i = 1; i <= n; i++) {
    int u = sa[i];
    if (u > n - K) continue;
    ++cnt[u % K];
    if (cnt[u % K] == (n - K) / K) {
      for (int j = u; j <= u + K - 1; j++) cout << (char)s[j];
      cout << '\n';
      return 0;
    }
  }
  return 0;
}

C.

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23;
const int inv2 = mod + 1 >> 1;
const int maxn = 2e5 + 52;
int a[maxn];

int add(int x, int y) { return (x + y >= mod) ? ((x + y) % mod) : x + y; }

struct SMT {
  vector<int> sum, tagx, tagd;

  SMT() {}
  SMT(const int &nn) { sum.resize(nn << 2), tagx.resize(nn << 2), tagd.resize(nn << 2); }

  void pushup(int p) { sum[p] = add(sum[p << 1], sum[p << 1 | 1]); }

  void build(int l, int r, int p) {
    tagx[p] = tagd[p] = 0;
    if (l == r) {
      sum[p] = a[l] % mod;
      return;
    }
    int mid = l + r >> 1;
    build(l, mid, p << 1);
    build(mid + 1, r, p << 1 | 1);
    pushup(p);
  }

  int calc(int l, int r, int fir, int d) {
    int cnt = r - l + 1, ret = 0;
    ret = (fir + (fir + (cnt - 1) * d % mod) % mod) % mod;
    ret = ret * cnt % mod * inv2 % mod;
    return ret;
  }

  void pushd(int l, int r, int p) {
    if (!tagx[p] && !tagd[p]) return;
    int mid = l + r >> 1;
    sum[p << 1] = add(sum[p << 1], calc(l, mid, tagx[p], tagd[p]));
    tagx[p << 1] = add(tagx[p << 1], tagx[p]);
    tagd[p << 1] = add(tagd[p << 1], tagd[p]);

    tagx[p] = add(tagx[p], (mid - l + 1) * tagd[p] % mod);

    sum[p << 1 | 1] = add(sum[p << 1 | 1], calc(mid + 1, r, tagx[p], tagd[p]));
    tagx[p << 1 | 1] = add(tagx[p << 1 | 1], tagx[p]);
    tagd[p << 1 | 1] = add(tagd[p << 1 | 1], tagd[p]);

    tagx[p] = tagd[p] = 0;
  }

  void upd(int ql, int qr, int l, int r, int p, int fir, int d) {
    if (ql <= l && r <= qr) {
      sum[p] = add(sum[p], calc(l, r, fir, d));
      tagx[p] = add(tagx[p], fir);
      tagd[p] = add(tagd[p], d);
      return;
    }
    pushd(l, r, p);
    int mid = l + r >> 1;
    if (mid >= qr) {
      upd(ql, qr, l, mid, p << 1, fir, d);
    } else if (mid < ql) {
      upd(ql, qr, mid + 1, r, p << 1 | 1, fir, d);
    } else {
      upd(ql, mid, l, mid, p << 1, fir, d);
      fir = add(fir, (mid - ql + 1) * d % mod);
      upd(mid + 1, qr, mid + 1, r, p << 1 | 1, fir, d);
    }
    pushup(p);
  }

  int qry(int ql, int qr, int l, int r, int p) {
    if (ql <= l && r <= qr) return sum[p];
    pushd(l, r, p);
    int mid = l + r >> 1, ans = 0;
    if (ql <= mid) ans = add(ans, qry(ql, qr, l, mid, p << 1));
    if (qr > mid) ans = add(ans, qry(ql, qr, mid + 1, r, p << 1 | 1));
    return ans;
  }
};

signed main() {
  ios ::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  int n, q;
  cin >> n;
  for (int i = 1; i <= n; i++) cin >> a[i];
  SMT smt(maxn + 1);
  smt.build(1, n, 1);
  cin >> q;
  while (q--) {
    int op;
    cin >> op;
    if (op == 1) {
      int l, r, fir, d;
      cin >> l >> r >> fir >> d;
      smt.upd(l, r, 1, n, 1, fir, d);
    } else {
      int l, r, m;
      cin >> l >> r >> m;
      int ans = smt.qry(l, r, 1, n, 1) % m;
      cout << ans << '\n';
    }
  }
  return 0;
}

D.

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
 
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
const int inv2 = (mod + 1) >> 1;
const int maxn = 1 << 18 | 100;
 
int read() {
    int x = 0;
    char c = getchar();
    while(! isdigit(c)) c = getchar();
    while(isdigit(c)) x = x * 10 + (c - 48), c = getchar();
    return x;
}
 
int add(int x, int y) {
    return (x + y >= mod) ? (x + y - mod) : (x + y);
}
int dec(int x, int y) {
    return (x - y < 0) ? (x - y + mod) : (x - y);
}
int mul(int x, int y) {
    return x * y % mod;
}
 
int qpow(int x, int y) {
    int res = 1;
    for(; y ; y >>= 1, x = x * x % mod)
        if(y & 1)
            res = res * x % mod;
    return res;
}
 
int rev[maxn];
void ntt(int *a, int lim, int inv) {
    for(int i = 0 ; i <= lim ; i ++)
        if(i < rev[i])
            swap(a[i], a[rev[i]]);
    for(int len = 1 ; len < lim ; len <<= 1) {
        int wn = qpow(3, (mod - 1) / (len << 1));
        if(inv == -1) wn = qpow(wn, mod - 2);
        for(int i = 0 ; i < lim ; i += len << 1) {
            int w = 1;
            for(int j = 0 ; j < len ; j ++) {
                int x = a[i + j], y = mul(a[i + j + len], w);
                a[i + j] = add(x, y);
                a[i + j + len] = dec(x, y);
                w = mul(w, wn);
            }
        }
    }
    if(inv == -1) {
        int invqwq = qpow(lim, mod - 2);
        for(int i = 0 ; i <= lim ; i ++)
            a[i] = mul(a[i], invqwq);
    }
}
 
void fwt(int *a, int lim, int inv) {
    for(int len = 1 ; len < lim ; len <<= 1) {
        for(int i = 0 ; i < lim ; i += len << 1) {
            for(int j = 0 ; j < len ; j ++) {
                int x = a[i + j];
                int y = a[i + j + len];
                a[i + j] = add(x, y);
                a[i + j + len] = dec(x, y);
                if(inv == -1) {
                    a[i + j] = mul(a[i + j], inv2);
                    a[i + j + len] = mul(a[i + j + len] , inv2);
                }
            }
        }
    }
}
 
int n;
int a[maxn],b[maxn],c[maxn],d[maxn];
int limit = 1,ans[maxn];
 
signed main(){
    n = read();
    for(register int i = 0 ; i <= n ; i ++)
        a[i] = read();
    for(register int i = 0 ; i <= n ; i ++)
        b[i] = read();
    for(register int i = 0 ; i <= n ; i ++)
        c[i] = read();
    for(register int i = 0 ; i <= n ; i ++)
        d[i] = read();
         
    int l = 0;
    limit = 1;
    while(limit <= n * 2)
        limit <<= 1, ++l;
         
    for(int i = 0 ; i < limit ; i ++)
        rev[i] = rev[i >> 1] >> 1 | (i & 1) << l - 1;
         
    for(int i = 0 ; i < (limit >> 1) ; i ++) {
        for(int j = i ;  ; j = (j - 1) & i) {
            ans[i] = add(ans[i], mul(a[j], b[i - j]));
            if(! j) break;
        }
    }
//  for(int i = 0 ; i < limit ; i ++)
//      cout << ans[i] << ' '; cout << '\n';
    ntt(ans, limit, 1);
    ntt(c, limit, 1);
    for(int i = 0 ; i < limit; i ++)
        ans[i] = mul(ans[i], c[i]);
    ntt(ans, limit, -1);
     
    fwt(ans, limit, 1);
    fwt(d, limit, 1);
    for(int i = 0 ; i < limit ; i ++)
        ans[i] = mul(ans[i], d[i]);
    fwt(ans, limit, -1);
     
    int _ = read();
    while(_ --) printf("%lld\n", ans[read()]);
    return 0;  
}

E.

#include<bits/stdc++.h>
using namespace std;
#define int long long
 
const int mod = 998244353;
int qpow(int x, int y) {
    int res = 1;
    for( ; y ; y >>= 1 , x = x * x % mod)
        if(y & 1)
            res = res * x % mod;
    return res;
}
 
int Inv(int x) {
    return qpow(x, mod - 2);
}
 
const int maxn = 1e6 + 61;
int fac[maxn << 1], inv[maxn << 1];
 
//void pre() {
//  for(int i = fac[0] = 1 ; i <= maxn ; i ++)
//      fac[i] = fac[i - 1] * i % mod;
//  inv[maxn] = Inv(fac[maxn]);
//  for(int i = maxn - 1; ~i; i --)
//      inv[i] = inv[i + 1] * (i + 1) % mod;
//}
//
//int C(int n, int m) {
//  if(n < m || n < 0 || m < 0) return 0;
//  return fac[n] % mod * inv[n - m] % mod * inv[m] % mod;
//}
void pre(int n) {
  inv[0] = 1;
  inv[1] = 1;
  for (int i = 2; i <= n; i++) {
    inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
  }
}
 
int C(int n, int m) {
  int res = 1;
  if (m > 1000000) m = n - m;
  for (int i = n; i >= n - m + 1; i--) res = 1ll * res * i % mod;
  for (int i = 1; i <= m; i++) res = 1ll * res * inv[i] % mod;
  return res;
}
 
int lucas(int n, int m) {
    if(n < m) return 0;
    if(m <= maxn) return C(n, m);
    return lucas(n / mod, m / mod) * lucas(n % mod, m % mod) % mod;
}
 
int solve(int n, int m) {
    int ans = ((qpow(m, n) - 2ll * lucas(n + m - 1, m - 1) % mod + m) % mod + mod) % mod;
    return ans;
}
 
signed main() {
    ios :: sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    pre(maxn);
    int _;
    cin >> _;
    while(_ --) {
        int n, m;
        cin >> n >> m;
        cout << solve(n, m) << '\n';
    }
    return 0;
}

F

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 52;
vector<int> d[maxn];
int f[maxn][20], dep[maxn];
vector<int> st, ed, g[maxn], rev;
struct mt {
  int n, cnt = 0;
  mt() {}
  mt(const int &nn) {
    n = nn, cnt = 0;
    st.resize(n + 1), ed.resize(n + 1);
    rev.resize(n << 1 | 1);
    for (int i = 1; i <= n; i++) g[i].clear();
    for (int i = 1; i < n; i++) {
      int u, v;
      cin >> u >> v;
      g[u].push_back(v);
      g[v].push_back(u);
    }
    dfs(dep[1] = 1);
    for (int j = 1; j <= 18; j++)
      for (int i = 1; i <= n; i++) f[i][j] = f[f[i][j - 1]][j - 1];
  }

  void dfs(int u) {
    rev[st[u] = ++cnt] = u;
    for (int v : g[u]) {
      if (v != f[u][0]) {
        dep[v] = dep[f[v][0] = u] + 1, dfs(v);
      }
    }
    rev[ed[u] = ++cnt] = u;
  }

  int lca(int x, int y) {
    if (dep[x] < dep[y]) swap(x, y);
    for (int i = 18; ~i; i--)
      if (dep[f[x][i]] >= dep[y]) x = f[x][i];
    if (x == y) return x;
    for (int i = 18; ~i; i--)
      if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
    return f[x][0];
  }
};

vector<int> a;

struct qry {
  int l, r, d;
};
vector<qry> Q;

int bl[maxn << 1];
struct mo_algorithm {
  int m, S;
  struct Qry {
    int l, r, lca, id;
    bool operator<(const Qry &rhs) const { return (bl[l] ^ bl[rhs.l]) ? bl[l] < bl[rhs.l] : r < rhs.r; }
  };
  vector<Qry> q;
  vector<int> vis, cnt, Ans;

  mo_algorithm() {}
  mo_algorithm(mt tr, const int &_m) {
    m = _m, S = 400, Ans.resize(m + 1), vis.resize(tr.cnt + 1), cnt.resize(maxn + 1);
    int tot = 0;
    for (int i = 1; i < (maxn << 1); i++) bl[i] = (i - 1) / S + 1;
    for (auto qq : Q) {
      int x = qq.l, y = qq.r;
      int lca = tr.lca(x, y);
      if (st[x] > st[y]) swap(x, y);
      if (x == lca) {
        q.push_back({ st[x], st[y], 0, ++tot });
      } else {
        q.push_back({ ed[x], st[y], lca, ++tot });
      }
    }
    solve();
  }

  void solve() {
    sort(q.begin(), q.end());
    int l = 1, r = 0, ans = 0;
    auto add = [&](int x) {
      if (++cnt[x] == 1) ++ans;
    };
    auto del = [&](int x) {
      if (--cnt[x] == 0) --ans;
    };
    auto Add = [&](int x) { (vis[x] ^= 1) ? add(a[x]) : del(a[x]); };
    for (auto x : q) {
      int ql = x.l, qr = x.r;
      while (l > ql) Add(rev[--l]);
      while (r < qr) Add(rev[++r]);
      while (l < ql) Add(rev[l++]);
      while (r > qr) Add(rev[r--]);
      if (x.lca) Add(x.lca);
      Ans[x.id] = ans;
      if (x.lca) Add(x.lca);
    }
  }
};

struct another {
  vector<int> cnt, Ans;
  int m;
  vector<pair<int, int>> q[maxn];

  another() {}
  another(mt tr, const int &_m) {
    m = _m, Ans.resize(m + 1), cnt.resize(maxn + 1);
    int tot = 0;
    for (auto qq : Q) {
      int x = qq.l, y = qq.r, d = qq.d;
      int lca = tr.lca(x, y), flca = f[lca][0];
      ++tot, q[x].push_back({ tot, d }), q[y].push_back({ tot, d });
      q[lca].push_back({ -tot, d }), q[flca].push_back({ -tot, d });
    }
    dfs(1);
  }

  void dfs(int u) {
    for (int x : d[a[u]]) ++cnt[x];
    for (auto x : q[u]) {
      int id = x.first, v = x.second;
      if (id < 0) {
        Ans[-id] -= cnt[v];
      } else {
        Ans[id] += cnt[v];
      }
    }
    for (int v : g[u])
      if (v != f[u][0]) dfs(v);
    for (int x : d[a[u]]) --cnt[x];
  }
};

signed main() {
  ios ::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  for (int i = 1; i < maxn; i++)
    for (int j = i; j < maxn; j += i) d[j].push_back(i);
  int _;
  cin >> _;
  int test = 0;
  while (_--) {
    ++test;
    cout << "Case #" << test << ":" << '\n';
    int n, m;
    cin >> n, a.resize(n + 1);
    for (int i = 1; i <= n; i++) cin >> a[i];
    mt tr(n);
    cin >> m;
    Q.clear();
    for (int i = 1; i <= m; i++) {
      int l, r, d;
      cin >> l >> r >> d;
      Q.push_back({ l, r, d });
    }
    mo_algorithm md(tr, m);
    another solve(tr, m);
    for (int i = 1; i <= m; i++) cout << (md.Ans[i] ^ solve.Ans[i]) << '\n';
  }
  return 0;
}
posted @ 2020-04-17 23:55  _Isaunoya  阅读(208)  评论(0编辑  收藏  举报