Do not play too long segment tree hand has been born
Problem A: highway
False desired title, apparently denominator \ (R & lt C_ {-}. 1 + L ^ 2 \) . The all sub-segments within the interval and the seeking out everything is.
Then consider the tree line interval merger, it can not seem to do it.
Then SX Red Sun Guo enlighten me, we can take the idea of a tree similar to stained, consider each edge can be after a few.
This is evident when comparing, for the \ ((R - i + 1 ) (i - L + 1) \) then the molecules is. \ (\ SUM \ _ Limits} {I = L ^ R & lt (R & lt - + I. 1) (I -. 1 + L) W_i \) .
Simplification is about \ (\ SUM \ _ Limits} {I = L ^ R & lt (R & lt -. 1 + L - the LR) W_i + (L + R & lt) W_i I - I 2 W_i ^ \) .
Note 3 segment tree Tag: \ (= W_i S_1, S_2 I = W_i, W_i S_3 = I ^ 2 \) .
Interval incorporated directly together.
Then consider modifying the right side, it is to add a \ (V (R & lt -. 1 + L - the LR) \) \ (V (L + R & lt) \ I SUM \) and $ -vi ^ 2 $.
再记\(s_4 = \sum i, s_5 = \sum i^2\).
This question would be finished.
Note pit:
- To that point, we maintain that line, we need to deal with it
- Able to open to open long long long long! ! Do not hesitate! ! If you WA20, and that is about to open long long did not open
#include <bits/stdc++.h>
#define ll long long
const int N = 100000 + 233;
ll n, m, sum[5]; char opt[5];
struct SegTree { ll l, r, s[8], tag; } t[N << 2];
inline void Pushup(ll p) {
for (int i = 1; i <= 3; i++)
t[p].s[i] = t[p << 1].s[i] + t[p << 1 | 1].s[i];
}
ll gcd(ll x, ll y) {
return y == 0 ? x : gcd(y, x % y);
}
void Build(ll p, ll l, ll r) {
t[p].l = l, t[p].r = r;
if (l == r) return (void) (t[p].s[4] = l, t[p].s[5] = l * l);
ll mid = (l + r) >> 1;
Build(p << 1, l, mid), Build(p << 1 | 1, mid + 1, r);
for (int i = 4; i <= 5; i++)
t[p].s[i] = t[p << 1].s[i] + t[p << 1 | 1].s[i];
}
inline void Add(ll p, ll k) {
t[p].s[1] += (t[p].r - t[p].l + 1) * k;
t[p].s[2] += k * t[p].s[4];
t[p].s[3] += k * t[p].s[5];
t[p].tag += k;
}
inline void Pushdown(ll p) {
Add(p << 1, t[p].tag), Add(p << 1 | 1, t[p].tag);
t[p].tag = 0;
}
void Change(ll p, ll l, ll r, ll v) {
if (l <= t[p].l && r >= t[p].r) return (void) Add(p, v);
ll mid = (t[p].l + t[p].r) >> 1;
if (t[p].tag) Pushdown(p);
if (l <= mid) Change(p << 1, l, r, v);
if (r > mid) Change(p << 1 | 1, l, r, v);
Pushup(p);
}
void Ask(ll p, ll l, ll r) {
if (l <= t[p].l && r >= t[p].r) {
for (int i = 1; i <= 3; i++)
sum[i] += t[p].s[i];
return;
}
ll mid = (t[p].l + t[p].r) >> 1;
if (t[p].tag) Pushdown(p);
if (l <= mid) Ask(p << 1, l, r);
if (r > mid) Ask(p << 1 | 1, l, r);
}
inline void print(ll x, ll y) {
ll g = gcd(x, y);
printf("%lld/%lld\n", x / g, y / g);
}
signed main() {
scanf("%lld%lld", &n, &m);
Build(1, 1, n);
for (ll i = 1, l, r; i <= m; i++) {
ll v;
scanf("%s%lld%lld", opt, &l, &r); r--;
if (opt[0] == 'C') {
scanf("%lld", &v), Change(1, l, r, v);
} else {
sum[1] = sum[2] = sum[3] = 0;
Ask(1, l, r);
ll a = (r - l + 1 - l * r) * sum[1] + (r + l) * sum[2] - sum[3];
ll b = (r - l + 2) * (r - l + 1) / 2;
print(a, b);
}
}
return 0;
}
Problem D: Sorting
Fourth listening to this problem (
The first hearing in the death house Xing Zeyu speak SJZEZ
The second victory in SDFZ listen high cold pigeon pigeon talk
The third time in TYWZ really listening to Red Sun Ricardo -SX get together to speak
Fourth giant giant koala listen to talk in HZ
Real public issues (
The most important point of this question is to ask only one location, and the answer is clearly monotone, you get away with half
Sorting arrangement to grind Ji too, turn into 01 sequences, 0 represents less than, greater than or equal to 1, so that it can maintain a "sort" process with the segment tree.
However, this problem of data over the water, bucket row optimization God what could go (((
#include <bits/stdc++.h>
const int N = 100005 + 233;
int n, m, q, ans, a[N];
struct Command { int l, r, op; } cmd[N];
struct SegTree {
int l, r, sum, tag;
#define l(p) tree[p].l
#define r(p) tree[p].r
#define sum(p) tree[p].sum
#define tag(p) tree[p].tag
#define ls(p) p << 1
#define rs(p) p << 1 | 1
} tree[N << 2];
inline int R() {
int a = 0; char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) a = a * 10 + c - '0', c = getchar();
return a;
}
void Build(int p, int l, int r, int v) {
l(p) = l, r(p) = r, tag(p) = -1;
if (l == r) return (void) (sum(p) = a[l] >= v);
int mid = (l + r) >> 1;
Build(ls(p), l, mid, v), Build(rs(p), mid + 1, r, v);
sum(p) = sum(ls(p)) + sum(rs(p));
}
void Pushdown(int p) {
if (tag(p) != -1) {
sum(ls(p)) = (r(ls(p)) - l(ls(p)) + 1) * tag(p);
sum(rs(p)) = (r(rs(p)) - l(rs(p)) + 1) * tag(p);
tag(ls(p)) = tag(rs(p)) = tag(p);
tag(p) = -1;
}
}
void Change(int p, int l, int r, int v) {
if (l <= l(p) && r >= r(p)) {
sum(p) = (r(p) - l(p) + 1) * v;
tag(p) = v;
} else {
Pushdown(p);
int mid = (l(p) + r(p)) >> 1;
if (l <= mid) Change(ls(p), l, r, v);
if (r > mid) Change(rs(p), l, r, v);
sum(p) = sum(ls(p)) + sum(rs(p));
}
}
int Query(int p, int l, int r) {
if (l <= l(p) && r >= r(p))
return sum(p);
Pushdown(p);
int mid = (l(p) + r(p)) >> 1, ret = 0;
if (l <= mid) ret += Query(ls(p), l, r);
if (r > mid) ret += Query(rs(p), l, r);
return ret;
}
bool Check(int x) {
Build(1, 1, n, x);
for (int i = 1; i <= m; i++) {
int cnt = Query(1, cmd[i].l, cmd[i].r);
if (cnt != 0 && cnt != cmd[i].r - cmd[i].l + 1) {
if (cmd[i].op) {
Change(1, cmd[i].l, cmd[i].l + cnt - 1, 1);
Change(1, cmd[i].l + cnt, cmd[i].r, 0);
} else {
Change(1, cmd[i].l, cmd[i].r - cnt, 0);
Change(1, cmd[i].r - cnt + 1, cmd[i].r, 1);
}
}
}
return Query(1, q, q);
}
signed main() {
n = R(), m = R();
for (int i = 1; i <= n; i++)
a[i] = R();
for (int i = 1; i <= m; i++)
cmd[i].op = R(), cmd[i].l = R(), cmd[i].r = R();
q = R();
int l = 1, r = n, mid;
while (l <= r) {
mid = (l + r) >> 1;
if (Check(mid)) {
ans = mid;
l = mid + 1;
} else r = mid - 1;
}
return !printf("%d\n", ans);
}