模板。
无。
#include
#define ioscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define me(a, x) memset(a, x, sizeof a)
#define all(a) a.begin(), a.end()
#define sz(a) ((int)(a).size())
#define pb(a) push_back(a)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair pii;
typedef vector> vvi;
typedef vector vi;
typedef vector vb;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
template
ostream &operator<<(ostream &os, const vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cout << a[i] << ' ';
return os;
}
template
istream &operator>>(istream &in, vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cin >> a[i];
return in;
}
/* ----------------- 有乘就强转,前缀和开ll ----------------- */
int v[N];
struct Node
{
int l, r;
int minn;
} tr[N * 4];
void pushup(int u)
{
tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
}
void build(int u, int l, int r)
{
if (l == r)
{
tr[u] = {l, r, v[l]};
return;
}
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, 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].minn;
}
int mid = tr[u].l + tr[u].r >> 1;
int minn = MAX;
if (l <= mid)
minn = min(minn, query(u << 1, l, r));
if (r > mid)
minn = min(minn, query(u << 1 | 1, l, r));
return minn;
}
void solve()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
cin >> v[i];
build(1, 1, n);
while (m--)
{
int l, r;
cin >> l >> r;
cout << query(1, l, r) << ' ';
}
cout << endl;
}
int main()
{
ioscc;
solve();
return 0;
}
模板。
无。
#include
#define ioscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define me(a, x) memset(a, x, sizeof a)
#define all(a) a.begin(), a.end()
#define sz(a) ((int)(a).size())
#define pb(a) push_back(a)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair pii;
typedef vector> vvi;
typedef vector vi;
typedef vector vb;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int MOD = 1e9 + 7;
const int N = 1e6 + 10;
template
ostream &operator<<(ostream &os, const vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cout << a[i] << ' ';
return os;
}
template
istream &operator>>(istream &in, vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cin >> a[i];
return in;
}
/* ----------------- 有乘就强转,前缀和开ll ----------------- */
int v[N];
struct Node
{
int l, r;
int minn, maxx;
} tr[N * 4];
void pushup(int u)
{
tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
tr[u].maxx = max(tr[u << 1].maxx, tr[u << 1 | 1].maxx);
}
void build(int u, int l, int r)
{
if (l == r)
{
tr[u] = {l, r, v[l], v[l]};
return;
}
tr[u] = {l, r, 0, 0};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
int queryMin(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r)
{
return tr[u].minn;
}
int mid = tr[u].l + tr[u].r >> 1;
int minn = MAX;
if (l <= mid)
minn = min(minn, queryMin(u << 1, l, r));
if (r > mid)
minn = min(minn, queryMin(u << 1 | 1, l, r));
return minn;
}
int queryMax(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r)
{
return tr[u].maxx;
}
int mid = tr[u].l + tr[u].r >> 1;
int maxx = MIN;
if (l <= mid)
maxx = max(maxx, queryMax(u << 1, l, r));
if (r > mid)
maxx = max(maxx, queryMax(u << 1 | 1, l, r));
return maxx;
}
void solve()
{
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; ++i)
cin >> v[i];
build(1, 1, n);
for (int i = 1; i <= n - k + 1; ++i)
cout << queryMin(1, i, i + k - 1) << ' ';
cout << endl;
for (int i = 1; i <= n - k + 1; ++i)
cout << queryMax(1, i, i + k - 1) << ' ';
cout << endl;
}
int main()
{
ioscc;
solve();
return 0;
}
模板。
无。
#include
#define ioscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define me(a, x) memset(a, x, sizeof a)
#define all(a) a.begin(), a.end()
#define sz(a) ((int)(a).size())
#define pb(a) push_back(a)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair pii;
typedef vector> vvi;
typedef vector vi;
typedef vector vb;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
template
ostream &operator<<(ostream &os, const vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cout << a[i] << ' ';
return os;
}
template
istream &operator>>(istream &in, vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cin >> a[i];
return in;
}
/* ----------------- 有乘就强转,前缀和开ll ----------------- */
struct Node
{
int l, r;
ll sum;
} tr[N * 4];
void pushup(int u)
{
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void build(int u, int l, int r)
{
if (l == r)
{
tr[u] = {l, r, 0};
return;
}
tr[u] = {l, r, 0};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
ll 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;
ll sum = 0;
if (l <= mid)
sum += query(u << 1, l, r);
if (r > mid)
sum += query(u << 1 | 1, l, r);
return sum;
}
void update(int u, int x, int v)
{
if (tr[u].l == x && tr[u].r == x)
tr[u].sum += v;
else
{
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid)
update(u << 1, x, v);
else
update(u << 1 | 1, x, v);
pushup(u);
}
}
void solve()
{
int n, m;
cin >> n >> m;
build(1, 1, n);
while (m--)
{
char op;
int a, b;
cin >> op >> a >> b;
if (op == 'x')
update(1, a, b);
else
cout << query(1, a, b) << endl;
}
}
int main()
{
ioscc;
solve();
return 0;
}
区间修改时使用一种类差分的思想,每次埋地雷的时候只在区间左右端点累加一次值,这样就将问题装换为了单点修改;查询时我们再使用前缀和思想统计区间 [l, r] 区间内的地雷数。具体实现就是使用线段树维护两个sum,既区间左端点的地雷和区间右端点的地雷;在查询区间 [l ,r] 时,就可以用 [1, r] 的起点数减去 [1, l] 的终点数。
无。
#include
#define ioscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define me(a, x) memset(a, x, sizeof a)
#define all(a) a.begin(), a.end()
#define sz(a) ((int)(a).size())
#define pb(a) push_back(a)
#define ls u << 1
#define rs u << 1 | 1
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair pii;
typedef vector> vvi;
typedef vector vi;
typedef vector vb;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
template
ostream &operator<<(ostream &os, const vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cout << a[i] << ' ';
return os;
}
template
istream &operator>>(istream &in, vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cin >> a[i];
return in;
}
/* ----------------- 有乘就强转,前缀和开ll ----------------- */
struct Node
{
int l, r;
int sum[2];
} tr[N * 4];
void pushup(int u, int k)
{
tr[u].sum[k] = tr[u << 1].sum[k] + tr[u << 1 | 1].sum[k];
}
void build(int u, int l, int r)
{
tr[u] = {l, r, 0, 0};
if (l == r)
return;
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
}
ll query(int u, int l, int r, int k)
{
if (tr[u].l >= l && tr[u].r <= r)
return tr[u].sum[k];
int mid = tr[u].l + tr[u].r >> 1;
ll sum = 0;
if (l <= mid)
sum += query(u << 1, l, r, k);
if (r > mid)
sum += query(u << 1 | 1, l, r, k);
return sum;
}
void update(int u, int x, int k)
{
if (tr[u].l == tr[u].r)
{
++tr[u].sum[k];
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid)
update(u << 1, x, k);
else
update(u << 1 | 1, x, k);
pushup(u, k);
}
void solve()
{
int n, m;
cin >> n >> m;
build(1, 1, n);
while (m--)
{
int op, l, r;
cin >> op >> l >> r;
if (op == 1)
update(1, l, 0), update(1, r, 1);
else
cout << query(1, 1, r, 0) - query(1, 1, l - 1, 1) << endl;
}
}
int main()
{
ioscc;
solve();
return 0;
}
模板。
开ll。
#include
#define ioscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define me(a, x) memset(a, x, sizeof a)
#define all(a) a.begin(), a.end()
#define sz(a) ((int)(a).size())
#define pb(a) push_back(a)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair pii;
typedef vector> vvi;
typedef vector vi;
typedef vector vb;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int MOD = 1e9 + 7;
const int N = 2e5 + 10;
template
ostream &operator<<(ostream &os, const vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cout << a[i] << ' ';
return os;
}
template
istream &operator>>(istream &in, vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cin >> a[i];
return in;
}
/* ----------------- 有乘就强转,前缀和开ll ----------------- */
ll v[N];
struct Node
{
int l, r;
ll sum;
ll add;
} tr[N * 4];
void pushup(int u)
{
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void pushdown(int u)
{
if (tr[u].add)
{
tr[u << 1].sum += tr[u].add * (tr[u << 1].r - tr[u << 1].l + 1);
tr[u << 1 | 1].sum += tr[u].add * (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1);
tr[u << 1].add += tr[u].add;
tr[u << 1 | 1].add += tr[u].add;
tr[u].add = 0;
}
}
void build(int u, int l, int r)
{
if (l == r)
{
tr[u] = {l, r, v[l], 0};
return;
}
tr[u] = {l, r, 0, 0};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
ll query(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r)
return tr[u].sum;
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
ll sum = 0;
if (l <= mid)
sum += query(u << 1, l, r);
if (r > mid)
sum += query(u << 1 | 1, l, r);
return sum;
}
void update(int u, int l, int r, int v)
{
if (tr[u].l >= l && tr[u].r <= r)
{
tr[u].sum += (ll)(tr[u].r - tr[u].l + 1) * v;
tr[u].add += v;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid)
update(u << 1, l, r, v);
if (r > mid)
update(u << 1 | 1, l, r, v);
pushup(u);
}
void solve()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
cin >> v[i];
build(1, 1, n);
while (m--)
{
int op;
int l, r, v;
cin >> op;
if (op == 1)
{
cin >> l >> r >> v;
update(1, l, r, v);
}
else if (op == 2)
{
cin >> v;
update(1, 1, 1, v);
}
else if (op == 3)
{
cin >> v;
update(1, 1, 1, -v);
}
else if (op == 4)
{
cin >> l >> r;
cout << query(1, l, r) << endl;
}
else
cout << query(1, 1, 1) << endl;
}
}
int main()
{
ioscc;
solve();
return 0;
}
线段树维护区间、最小值、区间和、懒标记。
更新懒标记时也需将节点的最小值加上懒标记的值。
#include
#define ioscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define me(a, x) memset(a, x, sizeof a)
#define all(a) a.begin(), a.end()
#define sz(a) ((int)(a).size())
#define pb(a) push_back(a)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair pii;
typedef vector> vvi;
typedef vector vi;
typedef vector vb;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int MOD = 1e9 + 7;
const int N = 2e5 + 10;
template
ostream &operator<<(ostream &os, const vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cout << a[i] << ' ';
return os;
}
template
istream &operator>>(istream &in, vector &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cin >> a[i];
return in;
}
/* ----------------- 有乘就强转,前缀和开ll ----------------- */
ull v[N];
struct Node
{
int l, r;
ull minn;
ull sum;
ull add;
} tr[N * 4];
void pushup(int u)
{
tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void pushdown(int u)
{
if (tr[u].add)
{
tr[u << 1].sum += tr[u].add * (tr[u << 1].r - tr[u << 1].l + 1);
tr[u << 1 | 1].sum += tr[u].add * (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1);
tr[u << 1].minn += tr[u].add;
tr[u << 1 | 1].minn += tr[u].add;
tr[u << 1].add += tr[u].add;
tr[u << 1 | 1].add += tr[u].add;
tr[u].add = 0;
}
}
void build(int u, int l, int r)
{
if (l == r)
{
tr[u] = {l, r, v[l], v[l], 0};
return;
}
tr[u] = {l, r, 0, 0, 0};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
ull querySum(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r)
{
return tr[u].sum;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
ull sum = 0;
if (l <= mid)
sum += querySum(u << 1, l, r);
if (r > mid)
sum += querySum(u << 1 | 1, l, r);
return sum;
}
ull queryMin(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r)
{
return tr[u].minn;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
ull minn = MAX;
if (l <= mid)
minn = min(minn, queryMin(u << 1, l, r));
if (r > mid)
minn = min(minn, queryMin(u << 1 | 1, l, r));
return minn;
}
void update(int u, int l, int r, int v)
{
if (tr[u].l >= l && tr[u].r <= r)
{
tr[u].sum += (ull)(tr[u].r - tr[u].l + 1) * v;
tr[u].minn += v;
tr[u].add += v;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid)
update(u << 1, l, r, v);
if (r > mid)
update(u << 1 | 1, l, r, v);
pushup(u);
}
void solve()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
cin >> v[i];
build(1, 1, n);
while (m--)
{
char op;
int a, b, c;
cin >> op;
if (op == 'M')
{
cin >> a >> b;
cout << queryMin(1, a, b) << endl;
}
else if (op == 'P')
{
cin >> a >> b >> c;
update(1, a, b, c);
}
else
{
cin >> a >> b;
cout << querySum(1, a, b) << endl;
}
}
}
int main()
{
ioscc;
solve();
return 0;
}