@Dmaxiya
2022-11-12T17:55:17.000000Z
字数 5361
阅读 1251
板子
int n;
int sum[maxn];
// 树状数组下标范围为[1, n],查询[1, i] 区间和
int lowbit(int x) {
return x & (-x);
}
void update(int i, int x) {
while(i <= n) {
sum[i] += x;
i += lowbit(i);
}
}
int query(int i) {
int ret = 0;
while(i > 0) {
ret += sum[i];
i -= lowbit(i);
}
return ret;
}
int n, m;
int sum[maxn][maxm];
// 树状数组下标范围为[(1, 1), (n, m)],查询[(1, 1), (i, j)] 区间和
int lowbit(int x) {
return x & (-x);
}
void update(int i, int j, int x) {
while(i <= n) {
int jj = j;
while(jj <= m) {
sum[i][jj] += x;
jj += lowbit(jj);
}
i += lowbit(i);
}
}
int query(int i, int j) {
int ret = 0;
while(i > 0) {
int jj = j;
while(jj > 0) {
ret += sum[i][jj];
jj -= lowbit(jj);
}
i -= lowbit(i);
}
return ret;
}
const int maxn = 100000 + 100;
const int Log = 40;
int stmax[maxn][Log], stmin[maxn][Log], mn[maxn];
int num[maxn];
// 下标范围为[1,n],每次查询区间为[L, R]
void Init() {
mn[0] = -1;
for(int i = 1; i <= n; ++i) {
mn[i] = ((i & (i - 1)) == 0)? mn[i - 1] + 1: mn[i - 1];
stmax[i][0] = stmin[i][0] = num[i];
}
for(int j = 1; j <= mn[n]; ++j) {
for(int i = 1; i + (1 << j) - 1 <= n; ++i) {
stmax[i][j] = max(stmax[i][j - 1], stmax[i + (1 << (j - 1))][j - 1]);
stmin[i][j] = min(stmin[i][j - 1], stmin[i + (1 << (j - 1))][j - 1]);
}
}
}
int rmq_max(int L, int R) {
int k = mn[R - L + 1];
return max(stmax[L][k], stmax[R - (1 << k) + 1][k]);
}
int rmq_min(int L, int R) {
int k = mn[R - L + 1];
return min(stmin[L][k], stmin[R - (1 << k) + 1][k]);
}
const int maxn = 50000 + 100;
struct SegmentTree {
int sum[maxn << 2], mx[maxn << 2], mn[maxn << 2];
inline int lson(int rt) {
return rt << 1;
}
inline int rson(int rt) {
return rt << 1 | 1;
}
void pushUp(int rt) {
int l = lson(rt);
int r = rson(rt);
sum[rt] = sum[l] + sum[r];
mx[rt] = max(mx[l], mx[r]);
mn[rt] = min(mn[l], mn[r]);
}
void build(int rt, int l, int r) {
if(l == r) {
scanf("%d", &sum[rt]);
mn[rt] = mx[rt] = sum[rt];
return ;
}
int m = (l + r) >> 1;
build(lson(rt), l, m);
build(rson(rt), m + 1, r);
pushUp(rt);
}
void update(int rt, int l, int r, int idx, int x) {
if(l == r) {
sum[rt] = mx[rt] = mn[rt] = x;
return ;
}
int m = (l + r) >> 1;
if(idx <= m) {
update(lson(rt), l, m, idx, x);
} else {
update(rson(rt), m + 1, r, idx, x);
}
pushUp(rt);
}
void add(int rt, int l, int r, int idx, int x) {
if(l == r) {
sum[rt] += x;
mx[rt] = mn[rt] = sum[rt];
return ;
}
int m = (l + r) >> 1;
if(idx <= m) {
add(lson(rt), l, m, idx, x);
} else {
add(rson(rt), m + 1, r, idx, x);
}
pushUp(rt);
}
int queryMax(int rt, int l, int r, int L, int R) {
if(L <= l && r <= R) {
return mx[rt];
}
int m = (l + r) >> 1;
int ret = INT_MIN;
if(L <= m) {
ret = max(ret, queryMax(lson(rt), l, m, L, R));
}
if(m < R) {
ret = max(ret, queryMax(rson(rt), m + 1, r, L, R));
}
return ret;
}
int queryMin(int rt, int l, int r, int L, int R) {
if(L <= l && r <= R) {
return mn[rt];
}
int m = (l + r) >> 1;
int ret = INT_MAX;
if(L <= m) {
ret = min(ret, queryMin(lson(rt), l, m, L, R));
}
if(m < R) {
ret = min(ret, queryMin(rson(rt), m + 1, r, L, R));
}
return ret;
}
int querySum(int rt, int l, int r, int L, int R) {
if(L <= l && r <= R) {
return sum[rt];
}
int m = (l + r) >> 1;
int ret = 0;
if(L <= m) {
ret += querySum(lson(rt), l, m, L, R);
}
if(R > m) {
ret += querySum(rson(rt), m + 1, r, L, R);
}
return ret;
}
};
const int maxn = 100000 + 100;
struct SegmentTree {
int sum[maxn << 2], lazy[maxn << 2];
inline int lson(int rt) {
return rt << 1;
}
inline int rson(int rt) {
return rt << 1 | 1;
}
void pushUp(int rt) {
sum[rt] = sum[lson(rt)] + sum[rson(rt)];
}
void pushDown(int rt, int len) {
if (lazy[rt] == 0) {
return ;
}
int l = lson(rt);
int r = rson(rt);
lazy[l] += lazy[rt];
lazy[r] += lazy[rt];
sum[l] += (len - (len >> 1)) * lazy[rt];
sum[r] += (len >> 1) * lazy[rt];
lazy[rt] = 0;
}
void build(int rt, int l, int r) {
lazy[rt] = 0;
if(l == r) {
scanf("%d", &sum[rt]);
return ;
}
int m = (l + r) >> 1;
build(lson(rt), l, m);
build(rson(rt), m + 1, r);
pushUp(rt);
}
void add(int rt, int l, int r, int L, int R, int x) {
if(L <= l && r <= R) {
lazy[rt] += x;
sum[rt] += (r - l + 1) * x;
return ;
}
pushDown(rt, r - l + 1);
int m = (l + r) >> 1;
if(L <= m) {
add(lson(rt), l, m, L, R, x);
}
if(m < R) {
add(rson(rt), m + 1, r, L, R, x);
}
pushUp(rt);
}
int query(int rt, int l, int r, int L, int R) {
if(L <= l && r <= R) {
return sum[rt];
}
pushDown(rt, r - l + 1);
int m = (l + r) >> 1;
int ret = 0;
if(L <= m) {
ret += query(lson(rt), l, m, L, R);
}
if(R > m) {
ret += query(rson(rt), m + 1, r, L, R);
}
return ret;
}
};
const int Log = 20;
const int maxn = 200000;
const int t_maxn = maxn * Log;
int n, cnt;
int root[maxn], Sum[t_maxn], lson[t_maxn], rson[t_maxn];
// cnt 每次需要清空为 0
// maxn 为主席树节点个数
// 线段树下标从 1 开始
// root[i] 为第 i 棵线段树的根节点
// Sum 为线段树,lson 和 rson 是节点 i 的左右子节点
void Build(int &x, int l, int r) {
x = cnt++;
Sum[x] = 0;
if(l == r) {
return ;
}
int m = (l + r) >> 1;
Build(lson[x], l, m);
Build(rson[x], m + 1, r);
}
void update(int &x, int last, int l, int r, int pos) {
x = cnt++;
lson[x] = lson[last];
rson[x] = rson[last];
if(l == r) {
Sum[x] = Sum[last] + 1;
return ;
}
int m = (l + r) >> 1;
if(pos <= m) {
update(lson[x], lson[last], l, m, pos);
} else {
update(rson[x], rson[last], m + 1, r, pos);
}
Sum[x] = Sum[lson[x]] + Sum[rson[x]];
}
int query(int L, int R, int l, int r, int k) {
if(l == r) {
return l;
}
int m = (l + r) >> 1;
int tmp = Sum[lson[R]] - Sum[lson[L]];
if(k <= tmp) {
return query(lson[L], lson[R], l, m, k);
} else {
return query(rson[L], rson[R], m + 1, r, k - tmp);
}
}
const int maxn = 1000000 + 100;
// 数组下标从 1 开始
struct Tree {
int root, top, n;
int sta[maxn], l[maxn], r[maxn];
bool vis[maxn];
void build(int *num, int nn) {
n = nn;
top = 0;
memset(l, 0, sizeof(int) * (n + 1));
memset(r, 0, sizeof(int) * (n + 1));
memset(vis, 0, sizeof(bool) * (n + 1));
for(int i = 1; i <= n; ++i) {
int tmp = top;
while(top > 0 && num[sta[top - 1]] < num[i]) {
--top;
}
if(top != 0) {
r[sta[top - 1]] = i;
}
if(top < tmp) {
l[i] = sta[top];
}
sta[top++] = i;
}
for(int i = 1; i <= n; ++i) {
vis[l[i]] = vis[r[i]] = true;
}
for(int i = 1; i <= n; ++i) {
if(!vis[i]) {
root = i;
}
}
}
};
const int maxn = 100000 + 100;
// 下标范围为 [1, n]
struct Node {
int l, r;
int id;
static int pos[maxn];
void init() {
int sz = sqrt(maxn);
for (int i = 0; i < maxn; ++i) {
pos[i] = i / sz;
}
}
};
int Node::pos[maxn] = {};
bool operator<(const Node &a, const Node &b) {
if(Node::pos[a.l] == Node::pos[b.l]) {
return a.r < b.r;
}
return Node::pos[a.l] < Node::pos[b.l];
}
int n, q, l, r, sz;
int ans[maxn];
Node node[maxn];
void add(int x);
void del(int x);
int getAns();
void mo() {
l = 1;
r = 0;
sort(node, node + q);
for (int i = 0; i < q; ++i) {
while (r < node[i].r) {
++r;
add(r);
}
while (l > node[i].l) {
--l;
add(l);
}
while (r > node[i].r) {
del(r);
--r;
}
while (l < node[i].l) {
del(l);
++l;
}
ans[node[i].id] = getAns();
}
}