文章目录
线段树
慢慢更新,之后加上思路解析等~~~~
1. 签到快签道
- 线段树维护:区间的最小值
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
#define ls u<<1
#define rs u<<1|1
struct node {
int l, r;
int v;
} tr[N << 2];
int n, q;
int a[N];
void pushup(int u) {
tr[u].v = min(tr[ls].v, tr[rs].v);
}
void build(int u, int l, int r) {
tr[u] = {l, r};
if(l == r) { tr[u].v = a[l]; return ; }
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
pushup(u);
}
int query(int u, int l, int r) {
if(tr[u].l >= l && tr[u].r <= r) return tr[u].v;
int mid = tr[u].l + tr[u].r >> 1;
int ans = 0x7fffffff;
if(l <= mid) ans = min(ans, query(ls, l, r));
if(r > mid) ans = min(ans, query(rs, l, r));
return ans;
}
int main() {
cin >> n >> q;
for (int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
while(q--) {
int l, r;
cin >> l >> r;
int res = 0x7fffffff;
if(l != 1) res = query(1, 1, l - 1);
if(r != n) res = min(res, query(1, r + 1, n));
cout << res << endl;
}
return 0;
}
2. XOR的艺术
- 线段树维护:区间的 1 {1} 1 的个数
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
#define ls u<<1
#define rs u<<1|1
struct node {
int l, r;
int v, add;
} tr[N << 2];
int a[N];
void pushup(int u) {
tr[u].v = tr[ls].v + tr[rs].v;
}
void pushdown(int u) {
if(tr[u].add) {
tr[u].add ^= 1;
tr[ls].add ^= 1, tr[rs].add ^= 1;
tr[ls].v = (tr[ls].r - tr[ls].l + 1) - tr[ls].v;
tr[rs].v = (tr[rs].r - tr[rs].l + 1) - tr[rs].v;
}
}
void build(int u, int l, int r) {
tr[u] = {l, r};
if(l == r) { tr[u].v = a[l] == 1 ? 1 : 0; return ; }
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
pushup(u);
}
int query(int u, int l, int r) {
if(tr[u].l >= l && tr[u].r <= r) return tr[u].v;
int mid = tr[u].l + tr[u].r >> 1;
pushdown(u);
int ans = 0;
if(l <= mid) ans = query(ls, l, r);
if(r > mid) ans += query(rs, l, r);
return ans;
}
void modify(int u, int l, int r) {
if(tr[u].l >= l && tr[u].r <= r) {
tr[u].add ^= 1;
tr[u].v = (tr[u].r - tr[u].l + 1) - tr[u].v;
return ;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modify(ls, l, r);
if(r > mid) modify(rs, l, r);
pushup(u);
}
int main() {
int n, m, p, l, r;
cin >> n >> m;
string s; cin >> s;
for(int i = 0; i < n; i++) a[i + 1] = s[i] - '0';
build(1, 1, n);
for(int i = 1; i <= m; i++) {
cin >> p >> l >> r;
if(p == 0)
modify(1, l, r);
if(p == 1)
cout << query(1, l, r) << endl;
}
return 0;
}
3. 魔法学院(easy version)
- 线段树维护:区间的最大值,区间推平。
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
#define ls u<<1
#define rs u<<1|1
struct Node {
int l, r, c;
bool operator<(const Node& A) const {
return c < A.c;
}
} op[N];
struct node {
int l, r;
int v;
} tr[N << 2];
int n, q, l, r, c;
string s;
void pushdown(int u) {
tr[ls].v = max(tr[ls].v, tr[u].v);
tr[rs].v = max(tr[rs].v, tr[u].v);
}
void build(int u, int l, int r) {
tr[u] = {l, r};
if(l == r) { tr[u].v = s[l]; return ; }
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
}
int query(int u, int x) {
if(tr[u].l >= x && tr[u].r <= x) return tr[u].v;
int mid = tr[u].l + tr[u].r >> 1;
pushdown(u);
int res = 0;
if(x <= mid) return query(ls, x);
return query(rs, x);
}
void modify(int u, int l, int r, int c) {
if(tr[u].l >= l && tr[u].r <= r) {
tr[u].v = max(tr[u].v, c);
return ;
}
int mid = tr[u].l + tr[u].r >> 1;
pushdown(u);
if(l <= mid) modify(ls, l, r, c);
if(r > mid) modify(rs, l, r, c);
}
int main() {
cin >> n >> q;
cin >> s; s = '#' + s;
for (int i = 0; i < q; i++) {
cin >> op[i].l >> op[i].r;
char c; cin >> c;
op[i].c = c;
}
sort(op, op + q);
build(1, 1, n);
for (int i = 0; i < q; i++) modify(1, op[i].l, op[i].r, op[i].c);
int res = 0;
for (int i = 1; i <= n; i++) {
res += query(1, i);
}
cout << res << endl;
return 0;
}
- 并查集(魔法学院(hard version))
#include <bits/stdc++.h>
using namespace std;
const int N = 10000010;
char s[N];
int a[N];
int n, m;
vector<pair<int, int>> q[127];
int fa[N];
int find(int x) {
return fa[x] = fa[x] == x ? x : find(fa[x]);
}
int main() {
scanf("%d%d", &n, &m);
scanf("%s", s + 1);
for (int i = 0; i <= n; i++) fa[i] = i;
int l, r;
char c;
while(m--) {
scanf("%d%d %c", &l, &r, &c);
q[c].push_back({l, r});
}
for (int i = 126; i >= 33; i--) {
for (int j = 0; j < q[i].size(); j++) {
l = q[i][j].first, r = q[i][j].second;
for (int k = find(r); k >= l; k = find(k)) {
s[k] = max(s[k], (char)i);
fa[k] = find(k - 1);
}
}
}
long long ans = 0;
for (int i = 1; i <= n; i++) ans += s[i];
printf("%d\n", ans);
return 0;
}
4. E - Meaningful Mean
- 线段树维护:区间值之和。
#include <bits/stdc++.h>
using namespace std;
#define ls u<<1
#define rs u<<1|1
#define int long long
const int N = 250010;
struct node {
int l, r;
int v;
} tr[N << 2];
int n, k, a[N], b[N];
void pushup(int u) {
tr[u].v = tr[ls].v + tr[rs].v;
}
void build(int u, int l, int r) {
tr[u] = {l, r};
if(l == r) return ;
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
}
int query(int u, int l, int r) {
if(tr[u].l >= l && tr[u].r <= r) return tr[u].v;
int mid = tr[u].l + tr[u].r >> 1;
int ans = 0;
if(l <= mid) ans = query(ls, l, r);
if(r > mid) ans += query(rs, l, r);
return ans;
}
void modify(int u, int x, int v) {
if(tr[u].l >= x && tr[u].r <= x) {
tr[u].v += v;
return ;
}
int mid = tr[u].l + tr[u].r >> 1;
if(x <= mid) modify(ls, x, v);
else modify(rs, x, v);
pushup(u);
}
signed main() {
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> a[i], a[i] -= k;
a[0] -= k;
for (int i = 1; i <= n; i++) a[i] += a[i - 1], b[i] = a[i];
b[0] = a[0];
sort(a, a + 1 + n);
for (int i = 0; i <= n; i++)
b[i] = lower_bound(a, a + 1 + n, b[i]) - a;
build(1, 0, n);
int res = 0;
// sum(r) >= sum(l - 1)
for (int i = 1; i <= n; i++) {
modify(1, b[i - 1], 1);
res += query(1, 0, b[i]);
}
cout << res << endl;
return 0;
}
5. 干饭得插队
- 线段树维护:区间值之和。
#include <bits/stdc++.h>
using namespace std;
#define ls u<<1
#define rs u<<1|1
const int N = 1000010;
struct node {
int l, r;
int v;
} tr[N << 2];
struct Node {
int id, val;
} a[N];
int n, k;
int ans[N];
int len(int u) {
return tr[u].r - tr[u].l + 1;
}
void pushup(int u) {
tr[u].v = tr[ls].v + tr[rs].v;
}
void build(int u, int l, int r) {
tr[u] = {l, r};
if(l == r) return ;
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
}
void modify(int u, int x, int v) {
if(tr[u].l == tr[u].r) {
tr[u].v += 1;
ans[tr[u].l] = v;
return ;
}
if(x <= len(ls) - tr[ls].v) modify(ls, x, v);
else modify(rs, x + tr[ls].v - len(ls), v);
pushup(u);
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i].id >> a[i].val;
build(1, 1, n);
for (int i = n; i >= 1; i--) {
int id = a[i].id + 1, val = a[i].val;
modify(1, id, val);
}
for (int i = 1; i <= n; i++) cout << ans[i] << ' ';
return 0;
}
6. 割韭菜
待补!!!
https://ac.nowcoder.com/acm/contest/30825/A
7. Rooks Defenders
- 板子,区间修改,区间查询
#include <bits/stdc++.h>
using namespace std;
#define ls u<<1
#define rs u<<1|1
#define int long long
const int N = 250000;
struct node{
int l, r;
int sum, add;
}tr[N << 2];
int a[N];
int n, m;
void pushup(int u) {
tr[u].sum = tr[ls].sum + tr[rs].sum;
}
int len(int u) {
return tr[u].r - tr[u].l + 1;
}
void pushdown(int u) {
if(tr[u].add) {
tr[ls].sum = tr[u].add * len(ls);
tr[rs].sum = tr[u].add * len(rs);
tr[ls].add = tr[u].add;
tr[rs].add = tr[u].add;
tr[u].add = 0;
}
}
void build(int u, int l, int r) {
tr[u] = {l, r, 0, 0};
if(l == r) { tr[u].sum = a[l]; tr[u].add = 0; return ;}
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
pushup(u);
}
void modify(int u, int l, int r, int x) {
if (tr[u].l >= l && tr[u].r <= r) {
tr[u].sum = len(u) * x;
tr[u].add = x;
return ;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modify(ls, l, r, x);
if(r > mid) modify(rs, l, r, x);
pushup(u);
}
int query(int u, int l, int r) {
if(tr[u].l >= l && tr[u].r <= r) { return tr[u].sum; }
int mid = tr[u].l + tr[u].r >> 1;
int v = 0;
pushdown(u);
if(l <= mid) v = query(ls, l, r);
if(r > mid) v += query(rs, l, r);
return v;
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
int op, x, v;
while(m--) {
cin >> op;
if(op == 1) {
cin >> x >> v;
modify(1, x, x, v);
} else {
cin >> x;
modify(1, 1, n, x);
}
cout << query(1, 1, n) << endl;
}
return 0;
}