牛客挑战赛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;
}