有N个整数,对这N个整数构造一颗线段树,每个结点用一个sum保留所代表区间的和。
建树后按照后续遍历,输出各个结点的sum。
输入格式
第一行,一个整数N。 1 <= N <= 100000。
第二行,N整数。每个整数范围[1,10^6]。
输出格式
一行, 若干个整数。
输入/输出例子1
输入:
5
3 6 8 2 9
输出:
3 6 9 8 17 2 9 11 28
样例解释
根结点1号结点,区间范围是[1,5]共5个结点,递归根结点的左子树,递归根结点的右子树。
#include <bits/stdc++.h> using namespace std; const int N=100005; struct treeNode { int l, r; long long sum; }tree[N<<2]; int n; long long a[N]; void build_stree(int cur, int l, int r) { tree[cur].l=l, tree[cur].r=r; if (l==r) { tree[cur].sum=a[l]; return; } int mid=l+r>>1, ls=cur*2, rs=cur*2+1; build_stree(ls, l, mid); build_stree(rs, mid+1, r); tree[cur].sum=tree[ls].sum+tree[rs].sum; } void dfs(int cur, int l, int r) { if (l==r) { printf("%lld ", tree[cur].sum); return; } int mid=tree[cur].l+tree[cur].r>>1, ls=cur*2, rs=cur*2+1; dfs(ls, l, mid); dfs(rs, mid+1, r); printf("%lld ", tree[cur].sum); } int main() { scanf("%d", &n); for (int i=1; i<=n; i++) scanf("%lld", &a[i]); build_stree(1, 1, n); dfs(1, 1, n); return 0; }
有N个整数,对这N个整数构造一颗线段树,每个结点用一个sum保留所代表区间的和。
有Q个询问,第i个询问给出s[i]和t[i],表示询问第s[i]个数至第t[i]个数的总和。
输入格式
第一行,N和Q。 1 <= N, Q <= 100000。
第二行,N个整数,每个整数范围[1,10^6]。
接下来有Q行,第i行是s[i]和t[i]。
输出格式
共Q行,每行一个整数。
输入/输出例子1
输入:
5 2
3 6 8 2 9
2 4
3 5
输出:
16
19
样例解释
本题纯粹是为了入门,请不要用部分和做。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N=100100; struct treeNode { int l, r; LL sum; }tree[N<<2]; int n, q, x, y; LL a[N]; void build_stree(int cur, int l, int r) { tree[cur].l=l, tree[cur].r=r; if (l==r) { tree[cur].sum=a[l]; return; } int mid=l+r>>1, ls=cur*2, rs=cur*2+1; build_stree(ls, l, mid); build_stree(rs, mid+1, r); tree[cur].sum=tree[ls].sum+tree[rs].sum; } LL query(int cur, int l, int r) { if (l<=tree[cur].l && tree[cur].r<=r) return tree[cur].sum; int mid=tree[cur].l+tree[cur].r>>1, ls=cur*2, rs=cur*2+1; LL sum1=0, sum2=0; if (l<=mid) sum1=query(ls, l, r); if (r>=mid+1) sum2=query(rs, l, r); return sum1+sum2; } int main() { scanf("%d%d", &n, &q); for (int i=1; i<=n; i++) scanf("%lld", &a[i]); build_stree(1, 1, n); while (q--) { scanf("%d%d", &x, &y); if (x>y) swap(x, y); printf("%lld\n", query(1, x, y)); } return 0; }
在N(1<=N<=100000)个数A1…An组成的序列上进行M(1<=M<=100000)次操作,操作有两种:
1 x y:表示修改A[x]为y;
2 x y:询问x到y之间的最大值。
输入格式
第一行输入N(1 <= N <= 100000),表示序列的长度,接下来N行输入原始序列;
接下来一行输入M(1 <= M <= 100000)表示操作的次数,接下来M行,每行为1 x y或2 x y
输出格式
对于每个操作(2)输出对应的答案。
输入/输出例子1
输入:
5
1
2
3
4
5
3
2 1 4
1 3 5
2 2 4
输出:
4
5
样例解释
【限制】
保证序列中的所有的数都在int范围内
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N=100100; struct treeNode { int l, r; LL mx; }tree[4*N]; int n, q, w, x, y; LL a[N]; void build_stree(int cur, int l, int r) { tree[cur].l=l, tree[cur].r=r; if (l==r) { tree[cur].mx=a[l]; return; } int mid=l+r>>1, ls=cur*2, rs=cur*2+1; build_stree(ls, l, mid); build_stree(rs, mid+1, r); tree[cur].mx=max(tree[ls].mx, tree[rs].mx); } LL query(int cur, int l, int r) { if (l<=tree[cur].l && tree[cur].r<=r) return tree[cur].mx; int mid=tree[cur].l+tree[cur].r>>1, ls=cur*2, rs=cur*2+1; LL mx1=0, mx2=0; if (l<=mid) mx1=query(ls, l, r); if (r>=mid+1) mx2=query(rs, l, r); return max(mx1, mx2); } void point_update(int cur, int pos, int val) { if (tree[cur].l==tree[cur].r && tree[cur].l==pos) { tree[cur].mx=val; return; } int mid=tree[cur].l+tree[cur].r>>1, ls=2*cur, rs=2*cur+1; if (pos<=mid) point_update(ls, pos, val); else if (pos>=mid+1) point_update(rs, pos, val); tree[cur].mx=max(tree[ls].mx, tree[rs].mx); } int main() { scanf("%d", &n); for (int i=1; i<=n; i++) scanf("%lld", &a[i]); scanf("%d", &q); build_stree(1, 1, n); while (q--) { scanf("%d%d%d", &w, &x, &y); //if (x>y) swap(x, y); if (w==1) point_update(1, x, y); else if (w==2) printf("%lld\n", query(1, x, y)); } return 0; }
在N(1 <= N <= 100000)个数A1…An组成的序列上进行M(1 <= M <= 100000)次操作,操作有两种:
1 L R C:表示把A[L]到A[R]增加C(C的绝对值不超过10000);
2 L R:询问A[L]到A[R]之间的最大值。
输入格式
第一行输入N(1 <= N <= 100000),表示序列的长度,接下来N行输入原始序列;
接下来一行输入M(1 <= M <= 100000)表示操作的次数,接下来M行,每行为1 L R C或2 L R
输出格式
对于每个操作(2)输出对应的答案。
输入/输出例子1
输入:
5
1
2
3
4
5
3
2 1 4
1 1 3 3
2 3 5
输出:
4
6
样例解释
【限制】
保证序列中的所有的数都在int范围内
在N(1 <= N <= 100000)个数A1…An组成的序列上进行M(1 <= M <= 100000)次操作,操作有两种:
1 L R C:表示把A[L]到A[R]增加C(C的绝对值不超过10000);
2 L R:询问A[L]到A[R]之间的总和。
输入格式
第一行输入N(1 <= N <= 100000),表示序列的长度,接下来N行输入原始序列;
接下来一行输入M(1 <= M <= 100000)表示操作的次数,接下来M行,每行为1 L R C或2 L R
输出格式
对于每个操作(2)输出对应的答案。
输入/输出例子1
输入:
5
1
2
3
4
5
3
2 1 4
1 1 3 3
2 3 5
输出:
10
15
样例解释
无
暂无