求问怎么缩短代码长度 我的代码实在是太长了,别人写 80 行的题我可能要写 100+。这是我的几份代码,有没有大佬能指点一下:
树套树
#include <bits/stdc++.h>
#define MAXN 500000
#define INF 2147483647
#define lc(p) p<<1
#define rc(p) p<<1|1
#define endl "\n"
using namespace std;
void read(int &x) {
x = 0; char c;
while ((c = getchar()) < '0' || c > '9');
while ('0' <= c && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
}
mt19937 rnd((int)('T' + 'Q') * time(0));
int idx, dl, dr, tmp;
int a[MAXN+5];
struct node {
int lc, rc;
int key, val, siz;
node() { key = val = siz = lc = rc = 0; }
} t[(MAXN<<3)+5];
struct fhq_treap {
int rt;
fhq_treap() { rt = 0; }
inline int newnode(int x) {
t[++idx].key = rnd();
t[idx].siz = 1, t[idx].val = x;
return idx;
}
inline void pushup(int p) { t[p].siz = t[t[p].lc].siz + 1 + t[t[p].rc].siz; }
inline void split(int p, int x, int &l, int &r) {
if (!p) {
l = r = 0;
return;
}
if (t[p].val <= x) {
l = p;
split(t[p].rc, x, t[p].rc, r);
} else {
r = p;
split(t[p].lc, x, l, t[p].lc);
}
pushup(p);
}
inline int merge(int l, int r) {
if (!l || !r) return l | r;
if (t[l].key <= t[r].key) {
t[l].rc = merge(t[l].rc, r);
pushup(l);
return l;
} else {
t[r].lc = merge(l, t[r].lc);
pushup(r);
return r;
}
}
inline void insert(int x) {
split(rt, x, dl, dr);
rt = merge(merge(dl, newnode(x)), dr);
}
inline void erase(int x) {
split(rt, x - 1, dl, dr);
split(dr, x, tmp, dr);
tmp = merge(t[tmp].lc, t[tmp].rc);
rt = merge(merge(dl, tmp), dr);
}
inline int lower(int x) {
split(rt, x - 1, dl, dr);
tmp = t[dl].siz;
rt = merge(dl, dr);
return tmp;
}
inline int upper(int x) {
split(rt, x, dl, dr);
tmp = t[dr].siz;
rt = merge(dl, dr);
return tmp;
}
inline int count(int x) {
split(rt, x - 1, dl, dr);
split(dr, x, tmp, dr);
x = t[tmp].siz;
rt = merge(merge(dl, tmp), dr);
return x;
}
inline int rank(int x) { return lower(x) + 1; }
inline int premax(int x) {
split(rt, x - 1, dl, dr);
if (!dl) {
rt = merge(dl, dr);
return -INF;
}
x = dl;
while (t[x].rc) x = t[x].rc;
rt = merge(dl, dr);
return t[x].val;
}
inline int sufmin(int x) {
split(rt, x, dl, dr);
if (!dr) {
rt = merge(dl, dr);
return INF;
}
x = dr;
while (t[x].lc) x = t[x].lc;
rt = merge(dl, dr);
return t[x].val;
}
};
struct Node {
int l, r;
fhq_treap f;
} seg[(MAXN<<2)+5];
inline void build(int p, int l, int r) {
for (int i = l; i <= r; ++i)
seg[p].f.insert(a[i]);
seg[p].l = l, seg[p].r = r;
if (l == r) return;
int mid = (l + r) >> 1;
build(lc(p), l, mid), build(rc(p), mid + 1, r);
}
inline void change(int p, int x, int y) {
seg[p].f.erase(a[x]), seg[p].f.insert(y);
if (seg[p].l == seg[p].r) {
a[x] = y;
return;
}
int mid = (seg[p].l + seg[p].r) >> 1;
if (x <= mid) change(lc(p), x, y);
else change(rc(p), x, y);
}
inline int lower(int l, int r, int x, int p = 1) {
if (seg[p].l > r || seg[p].r < l) return 0;
if (l <= seg[p].l && seg[p].r <= r) return seg[p].f.lower(x);
return lower(l, r, x, lc(p)) + lower(l, r, x, rc(p));
}
inline int Rank(const int &l, const int & r, const int & x) { return lower(l, r, x) + 1; }
inline int premax(int l, int r, int x, int p = 1) {
if (seg[p].l > r || seg[p].r < l) return -INF;
if (l <= seg[p].l && seg[p].r <= r) return seg[p].f.premax(x);
return max(premax(l, r, x, lc(p)), premax(l, r, x, rc(p)));
}
inline int sufmin(int l, int r, int x, int p = 1) {
if (seg[p].l > r || seg[p].r < l) return INF;
if (l <= seg[p].l && seg[p].r <= r) return seg[p].f.sufmin(x);
return min(sufmin(l, r, x, lc(p)), sufmin(l, r, x, rc(p)));
}
signed main() {
int n, m; read(n), read(m);
for (int i = 1; i <= n; ++i) read(a[i]);
build(1, 1, n);
while (m--) {
int opt, l, r, x, y;
read(opt);
if (opt == 1) {
read(l), read(r), read(x);
printf("%d\n", Rank(l, r, x));
} else if (opt == 2) {
read(l), read(r), read(x);
int L = 0, R = 1e8, ans;
while (L <= R) {
int mid = (L + R) >> 1;
if (Rank(l, r, mid) <= x) L = mid + 1, ans = mid;
else R = mid - 1;
}
printf("%d\n", ans);
} else if (opt == 3) {
read(x), read(y);
change(1, x, y);
} else if (opt == 4) {
read(l), read(r), read(x);
printf("%d\n", premax(l, r, x));
} else {
read(l), read(r), read(x);
printf("%d\n", sufmin(l, r, x));
}
}
return 0;
}
点分治
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N = 2e5;
int n, rt, ans, siz[N+5], d[N+5], fr[N+5], cnt[N+5];
bool vis[N+5];
struct edge {int v,w;};vector<edge> G[N+5];
vector<int> num, v[N+5];
void groot(int x, int fa, int sum) {
int mx = 0;
siz[x] = 1;
for (edge p : G[x]) {
int y = p.v, c = p.w;
if (y == fa || vis[y]) continue;
groot(y, x, sum);
siz[x] += siz[y];
mx = max(mx, siz[y]);
}
mx = max(mx, sum - siz[x]);
if (mx <= (sum + 1) / 2) rt = x;
}
void gdis(int x, int fa) {
v[fr[x]].push_back(x);
num.push_back(x);
for (edge p : G[x]) {
int y = p.v, c = p.w;
if (y == fa || vis[y]) continue;
d[y] = (d[x] + c) % 3;
if (!fa) fr[y] = y;
else fr[y] = fr[x];
gdis(y, x);
}
}
void calc(int x) {
fr[x] = x, d[x] = 0;
num.clear();
gdis(x, 0);
for (int x : num) ++cnt[d[x]];
for (int x : num) {
for (int y : v[fr[x]]) --cnt[d[y]];
for (int y : v[fr[x]]) ans += cnt[(3 - d[y]) % 3];
for (int y : v[fr[x]]) ++cnt[d[y]];
v[fr[x]].clear();
}
for (int x : num) cnt[d[x]] = 0;
}
void dfs(int x) {
calc(x);
vis[x] = 1;
for (edge p : G[x]) {
int y = p.v;
if (!vis[y]) {
groot(y, x, 0); groot(y, x, siz[y]);
dfs(rt);
}
}
}
signed main() {
// ios::sync_with_stdio(false);
// cin.tie(nullptr), cout.tie(nullptr);
cin >> n;
for (int i = 1; i < n; ++i) {
int u, v, w;
cin >> u >> v >> w;
G[u].push_back({v, w}), G[v].push_back({u, w});
}
dfs(1);
int x = ans + n, y = n * n;
int g = __gcd(x, y);
x /= g, y /= g;
cout << x << "/" << y << endl;
return 0;
}
线段树:
#include <bits/stdc++.h>
#define MAXN 200000
#define INF 2147483647
#define lc(p) p<<1
#define rc(p) p<<1|1
#define endl "\n"
using namespace std;
void read(int &x) {
x = 0; char c; bool f = 1;
while ((c = getchar()) < '0' || c > '9')
if (c == '-') f ^= 1;
while ('0' <= c && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
x = f ? x : -x;
}
mt19937 rnd(1000);
int idx, dl, dr, tmp;
int a[MAXN+5];
struct node {
int l, r;
int mx[2], cnt[2];
node() {
mx[0] = mx[1] = -INF;
cnt[0] = cnt[1] = 0;
l = r = 0;
}
} seg[(MAXN<<2)+5], emp;
node merge(node a, node b) {
node c; c.l = a.l, c.r = b.r;
if (a.mx[0] > b.mx[0]) {
c.mx[0] = a.mx[0], c.cnt[0] = a.cnt[0];
if (a.mx[1] > b.mx[0]) c.mx[1] = a.mx[1], c.cnt[1] = a.cnt[1];
else if (a.mx[1] < b.mx[0]) c.mx[1] = b.mx[0], c.cnt[1] = b.cnt[0];
else c.mx[1] = a.mx[1], c.cnt[1] = a.cnt[1] + b.cnt[0];
} else if (a.mx[0] < b.mx[0]) {
c.mx[0] = b.mx[0], c.cnt[0] = b.cnt[0];
if (b.mx[1] > a.mx[0]) c.mx[1] = b.mx[1], c.cnt[1] = b.cnt[1];
else if (b.mx[1] < a.mx[0]) c.mx[1] = a.mx[0], c.cnt[1] = a.cnt[0];
else c.mx[1] = b.mx[1], c.cnt[1] = b.cnt[1] + a.cnt[0];
} else {
c.mx[0] = b.mx[0], c.cnt[0] = a.cnt[0] + b.cnt[0];
if (b.mx[1] > a.mx[1]) c.mx[1] = b.mx[1], c.cnt[1] = b.cnt[1];
else if (b.mx[1] < a.mx[1]) c.mx[1] = a.mx[1], c.cnt[1] = a.cnt[1];
else c.mx[1] = b.mx[1], c.cnt[1] = b.cnt[1] + a.cnt[1];
}
return c;
}
void build(int p, int l, int r) {
seg[p].l = l, seg[p].r = r;
if (l == r) {
seg[p].cnt[0] = 1, seg[p].mx[0] = a[l];
seg[p].cnt[1] = 0, seg[p].mx[1] = 0;
return;
}
int mid = (l + r) >> 1;
build(lc(p), l, mid), build(rc(p), mid + 1, r);
seg[p] = merge(seg[lc(p)], seg[rc(p)]);
// cout<<l<<' '<<r<<":\n";
// cout<<seg[p].cnt[0]<<' '<<seg[p].cnt[1]<<endl;
}
void change(int p, int x, int y) {
if (seg[p].l == seg[p].r) {
seg[p].cnt[0] = 1, seg[p].mx[0] = y;
seg[p].cnt[1] = 0, seg[p].mx[1] = 0;
return;
}
int mid = (seg[p].l + seg[p].r) >> 1;
if (x <= mid) change(lc(p), x, y);
else change(rc(p), x, y);
seg[p] = merge(seg[lc(p)], seg[rc(p)]);
}
node query(int p, int l, int r) {
if (seg[p].l > r || seg[p].r < l) return emp;
if (l <= seg[p].l && seg[p].r <= r) {
// cout<<seg[p].l<<' '<<seg[p].r<<endl;
return seg[p];
}
return merge(query(lc(p), l, r), query(rc(p), l, r));
}
signed main() {
int n, m; read(n), read(m);
for (int i = 1; i <= n; ++i) read(a[i]);
build(1, 1, n);
while (m--) {
int opt, l, r, x, y;
read(opt);
if (opt == 1) {
read(x), read(y);
change(1, x, y);
} else {
read(l), read(r);
node ans = query(1, l, r);
printf("%d\n", ans.cnt[1]);
}
}
return 0;
}