Question.A[Uploaded by ZJ]
#include<iostream>
using namespace std;
const int MAX = 1e6 + 10;
struct s
{
int left, right;
int maxx, minn;
}tree[MAX << 2];
int n, q;
void btree(int k, int l, int r)
{
tree[k].left = l;
tree[k].right = r;
if (l == r)
{
scanf("%d", &tree[k].maxx);
tree[k].minn = tree[k].maxx;
return;
}
int mid = (tree[k].left + tree[k].right) >> 1;
btree(k << 1, l, mid);
btree(k << 1 | 1, mid + 1, r);
tree[k].maxx = max(tree[k << 1].maxx, tree[k << 1 | 1].maxx);
tree[k].minn = min(tree[k << 1].minn, tree[k << 1 | 1].minn);
}
int ma, mi;
void query(int k, int a, int b)
{
if (tree[k].left >= a && tree[k].right <= b)
{
ma = max(ma, tree[k].maxx);
mi = min(mi, tree[k].minn);
return;
}
int mid = (tree[k].left + tree[k].right) >> 1;
if (mid < a)
{
query(k << 1 | 1, a, b);
}
else if (mid >= b)
{
query(k << 1, a, b);
}
else
{
query(k << 1, a, b);
query(k << 1 | 1, a, b);
}
return;
}
int main()
{
scanf("%d%d", &n, &q);
btree(1, 1, n);
int p;
while (q--)
{
mi = MAX;
ma = -1;
int a, b;
scanf("%d%d", &a, &b);
query(1, a, b);
printf("%d\n", ma - mi);
}
return 0;
}
Question.B [Uploaded by HYT]
#include <iostream>
using namespace std;
const int N = 100010;
int a, b;// 查询的区间
int sum;
struct trees
{
int l, r;// 左右区间
int col;// 颜色 个数 位运算 计数
bool pure_is;// 判断是否是纯色
}tree[N * 4 + 1];
void build_tree(int l, int r, int k)// 建树
{
tree[k].l = l, tree[k].r = r;
tree[k].col = 1, tree[k].pure_is = true;
if (l == r)
{
return;
}
int mid = l + r >> 1;
build_tree(l, mid, k << 1);
build_tree(mid + 1, r, k << 1 | 1);
}
void pushup(int k) // 更新状态
{
tree[k].col = tree[k << 1].col | tree[k << 1 | 1].col;// 二进制 按位或 数位上有 1的 位置 代表这不同颜色
}
void pushdown(int k)// 传导纯色的lazy 标记
{
tree[k << 1].pure_is = 1;
tree[k << 1].col = tree[k].col;
tree[k << 1 | 1].pure_is = 1;
tree[k << 1 | 1].col = tree[k].col;
tree[k].pure_is = 0;
}
void update(int val, int k)// val 是颜色 ,k 是结点编号
{
if (tree[k].l >= a && tree[k].r <= b)
{
tree[k].col = val;
tree[k].pure_is = true;
return;
}
if (tree[k].col == val) return;// 如果颜色一样直接返回
if (tree[k].pure_is) pushdown(k); // 如果是纯色 在搜索之前下传
int mid = tree[k].l + tree[k].r >> 1;
if (a <= mid) update(val, k << 1);
if (b > mid) update(val, k << 1 | 1);
pushup(k);// 更新 维护的数据
return;
}
void query(int k)
{
if (tree[k].l >= a && tree[k].r <= b)
{
sum |= tree[k].col;// 计算 颜色
return;
}
if (tree[k].pure_is)
{
sum |= tree[k].col;
return;
}
int mid = tree[k].l + tree[k].r >> 1;
if (a <= mid) query(k << 1);
if (b > mid) query(k << 1 | 1);
return;
}
int solve()
{
int ans = 0;
while (sum)
{
if (sum & 1) ans++;
sum >>= 1;
}
return ans;
}
int main()
{
int l, t, o;
while (cin >> l >> t >> o)
{
build_tree(1, l, 1);
while (o--)
{
int val;
sum = 0;
char op[2];
cin >> op;
if (op[0] == 'C')
{
scanf("%d %d %d", &a, &b, &val);
if (a > b) swap(a, b);
update(1 << (val - 1), 1);// 更新数据
}
else
{
scanf("%d %d", &a, &b);
if (a > b) swap(a, b);
query(1);// 询问操作
cout << solve() << endl;
}
}
}
return 0;
}
Question.C [Uploaded by CZW]
#include <iostream>
#include <algorithm>
using namespace std;
int ans;
struct node
{
int lc, rc, mc, sum; //从该点左往右,从右往左,全部的最大连续子串和,sum表示从1到该点的和
}tree[2000100];
void build(int k, int x, int y)
{
if (x == y)
{
tree[k].mc = tree[k].lc = tree[k].rc = tree[x].sum - tree[x - 1].sum;
return;
}
int mid = x + y >> 1;
build(k << 1, x, mid);
build(k << 1 | 1, mid + 1, y);
tree[k].lc = max(tree[k << 1].lc, tree[mid].sum - tree[x - 1].sum + tree[k << 1 | 1].lc);
tree[k].rc = max(tree[k << 1 | 1].rc, tree[y].sum - tree[mid].sum + tree[k << 1].rc);
tree[k].mc = max(max(tree[k << 1].mc, tree[k << 1 | 1].mc), tree[k << 1 | 1].lc + tree[k << 1].rc);
}
int query(int k, int x, int y, int l, int r, int flag) //在x-y内查找l-r的结果,flag=-1表示查左往右,=1表示查右往左
{
if (l <= x && y <= r)
{
ans = max(ans, tree[k].mc);
return (flag == -1 ? tree[k].lc : tree[k].rc);
}
int mid = x + y >> 1;
if (r <= mid)
{
return query(k << 1, x, mid, l, r, -1);
}
else if (l > mid)
{
return query(k << 1 | 1, mid + 1, y, l, r, 1);
}
else
{
int ln = query(k << 1, x, mid, l, r, 1);
int rn = query(k << 1 | 1, mid + 1, y, l, r, -1);
ans = max(ln + rn, ans);
if (flag == -1)
{
return max(tree[k << 1].lc, tree[mid].sum - tree[x - 1].sum + rn);
}
else
{
return max(tree[k << 1 | 1].rc, tree[y].sum - tree[mid].sum + ln);
}
}
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
scanf("%d", &tree[i].sum);
tree[i].sum += tree[i - 1].sum;
}
build(1, 1, n);
int m;
cin >> m;
while (m--)
{
int l, r;
scanf("%d%d", &l, &r);
ans = tree[l].sum - tree[l - 1].sum;
query(1, 1, n, l, r, -1);
printf("%d\n", ans);
}
return 0;
}
Question.D [Uploaded by CZW]
#include <iostream>
#include <algorithm>
using namespace std;
int ans;
struct node
{
int lc, rc, mc, sum, num; //从该点左往右,从右往左,全部的最大连续子串和,sum表示从1到该点的和,num表示该点的值
}tree[2000100];
void build(int k, int x, int y)
{
if (x == y)
{
tree[k].mc = tree[k].lc = tree[k].rc = tree[k].sum = tree[x].num;
return;
}
int mid = x + y >> 1;
build(k << 1, x, mid);
build(k << 1 | 1, mid + 1, y);
tree[k].sum = tree[k << 1].sum + tree[k << 1 | 1].sum;
tree[k].lc = max(tree[k << 1].lc, tree[k << 1].sum + tree[k << 1 | 1].lc);
tree[k].rc = max(tree[k << 1 | 1].rc, tree[k << 1 | 1].sum + tree[k << 1].rc);
tree[k].mc = max(max(tree[k << 1].mc, tree[k << 1 | 1].mc), tree[k << 1 | 1].lc + tree[k << 1].rc);
}
int query(int k, int x, int y, int l, int r, int flag) //在x-y内查找l-r的结果,flag=-1表示查左往右,=1表示查右往左
{
if (l <= x && y <= r)
{
ans = max(ans, tree[k].mc);
return (flag == -1 ? tree[k].lc : tree[k].rc);
}
int mid = x + y >> 1;
if (r <= mid)
{
return query(k << 1, x, mid, l, r, -1);
}
else if (l > mid)
{
return query(k << 1 | 1, mid + 1, y, l, r, 1);
}
else
{
int ln = query(k << 1, x, mid, l, r, 1);
int rn = query(k << 1 | 1, mid + 1, y, l, r, -1);
ans = max(ln + rn, ans);
if (flag == -1)
{
return max(tree[k << 1].lc, tree[k << 1].sum + rn);
}
else
{
return max(tree[k << 1 | 1].rc, tree[k << 1 | 1].sum + ln);
}
}
}
void fix(int k, int x, int y, int loc, int NUM)
{
if (x == y)
{
tree[k].mc = tree[k].lc = tree[k].rc = tree[k].sum = NUM;
return;
}
int mid = x + y >> 1;
if (loc <= mid)
{
fix(k << 1, x, mid, loc, NUM);
}
else
{
fix(k << 1 | 1, mid + 1, y, loc, NUM);
}
tree[k].sum = tree[k << 1].sum + tree[k << 1 | 1].sum;
tree[k].lc = max(tree[k << 1].lc, tree[k << 1].sum + tree[k << 1 | 1].lc);
tree[k].rc = max(tree[k << 1 | 1].rc, tree[k << 1 | 1].sum + tree[k << 1].rc);
tree[k].mc = max(max(tree[k << 1].mc, tree[k << 1 | 1].mc), tree[k << 1 | 1].lc + tree[k << 1].rc);
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
scanf("%d", &tree[i].num);
}
build(1, 1, n);
int m;
cin >> m;
while (m--)
{
int l, r, op;
scanf("%d%d%d", &op, &l, &r);
if (op == 1)
{
ans = tree[l].num;
query(1, 1, n, l, r, -1);
printf("%d\n", ans);
}
else
{
tree[l].num = r;
fix(1, 1, n, l, r);
}
}
return 0;
}
Question.E [Uploaded by GSH]
#include <iostream>
typedef long long LL;
const int MAXN = 1e5 + 5;
int n, m;
struct node
{
int l, r, ans;
double Maxn;
#define l(p) tree[p].l
#define r(p) tree[p].r
#define ans(p) tree[p].ans
#define Maxn(p) tree[p].Maxn
}tree[MAXN << 2];
int Read()
{
int sum = 0, fh = 1; char ch = getchar();
for (; ch < '0' || ch > '9'; ch = getchar())
fh -= (ch == '-') << 1;
for (; ch >= '0' && ch <= '9'; ch = getchar())
sum = sum * 10 + (ch ^ 48);
return sum * fh;
}
double Max(double fir, double sec)
{
return (fir > sec) ? fir : sec;
}
double Min(double fir, double sec)
{
return (fir < sec) ? fir : sec;
}
void Build(int p, int l, int r)
{
l(p) = l, r(p) = r;
if (l == r)
return;
int mid = (l(p) + r(p)) >> 1;
Build(p << 1, l, mid);
Build(p << 1 | 1, mid + 1, r);
}
int Ask(int p, double k)
{
if (Maxn(p) <= k)
return 0;
if (l(p) == r(p))
return (Maxn(p) > k);
if (Maxn(p << 1) <= k)
return Ask(p << 1 | 1, k);
return ans(p) - ans(p << 1) + Ask(p << 1, k);
}
void Change(int p, int x, int k)
{
if (l(p) == r(p) && l(p) == x)
{
ans(p) = 1;
Maxn(p) = (double)k / x;
return;
}
int mid = (l(p) + r(p)) >> 1;
if (x <= mid)
Change(p << 1, x, k);
else
Change(p << 1 | 1, x, k);
Maxn(p) = Max(Maxn(p << 1), Maxn(p << 1 | 1));
ans(p) = ans(p << 1) + Ask(p << 1 | 1, Maxn(p << 1));
}
int main()
{
n = Read(), m = Read(); Build(1, 1, n);
for (int i = 1; i <= m; ++i)
{
int x = Read(), y = Read();
Change(1, x, y);
printf("%d\n", ans(1));
}
return 0;
}
为啥到E题就没了?因为还在等官giegie写[可怜]