//笑呵呵, 大自然的搬运工。
1、区间求和
#include <cstdio> #define N 1000001 int a[N]; struct node { int left, right, sum; }num[3*N]; int build(int left, int right, int cnt) { int mid; num[cnt].left=left; num[cnt].right=right; num[cnt].sum=0; mid=(left+right)>>1; if(left==right) return num[cnt].sum=a[left]; else return num[cnt].sum=build(left, mid, cnt*2)+build(mid+1, right, cnt*2+1); } int query(int left, int right, int cnt) { int mid; if(num[cnt].left==left&&num[cnt].right==right) return num[cnt].sum; mid=(num[cnt].left+num[cnt].right)>>1; if(right<=mid) return query(left, right, cnt*2); else if(left>mid) return query(left, right, cnt*2+1); else return query(left, mid, cnt*2)+query(mid+1, right, cnt*2+1); } int main() { int n, m, i, begin, end; while(scanf("%d%d", &n, &m) != EOF) { for(int i=1; i<=n; i++) scanf("%d", &a[i]); build(1, n, 1); while(m--) { scanf("%d%d", &begin, &end); printf("%d\n", query(begin, end, 1)); } } return 0; }
2、
单点更新+区间求和
#include <cstdio> #define N 1000001 int a[N]; struct node { int left, right, sum; }num[3*N]; int build(int left, int right, int cnt) { int mid; num[cnt].left=left; num[cnt].right=right; num[cnt].sum=0; mid=(left+right)>>1; if(left==right) return num[cnt].sum=a[left]; else return num[cnt].sum=build(left, mid, cnt*2)+build(mid+1, right, cnt*2+1); } int query(int left, int right, int cnt) { if(num[cnt].left==left&&num[cnt].right==right) return num[cnt].sum; int mid=(num[cnt].left+num[cnt].right)>>1; if(right<=mid) return query(left, right, cnt*2); else if(left>mid) return query(left, right, cnt*2+1); else return query(left, mid, cnt*2)+query(mid+1, right, cnt*2+1); } int add(int pos, int count, int cnt) { int mid; num[cnt].sum+=count; if(num[cnt].left==num[cnt].right) return 0; mid=(num[cnt].left+num[cnt].right)>>1; if(pos<=mid) //Notice; add(pos, count, cnt*2); else add(pos, count, cnt*2+1); } int main() { int n, m, i, b, d; char s[10]; while(scanf("%d%d", &n, &m)!= EOF) { for(int i=1; i<=n; i++) scanf("%d", &a[i]); build(1, n, 1); while(m--) { scanf("%s%d%d", s, &b, &d); if(s[0]=='Q') printf("%d\n", query(b, d, 1)); else add(b, d, 1); } } return 0; }
3、
区间最值差
#include <cstdio> #define N 100001 //#define MIN(a, b)(a)<(b)?(a):(b) //#define MAX(a, b)(a)>(b)?(a):(b) const int INF = 0x3f3f3f3f; int a[N]; struct node { int left, right, max, min; }num[N*3]; int Max, Min; int MAX(int a, int b) { if(a>b) return a; return b; } int MIN(int a, int b) { if(a<b) return a; return b; } void build(int left, int right, int cnt) { int mid; num[cnt].left=left; num[cnt].right=right; mid=(left+right)>>1; if(left==right) { scanf("%d", &num[cnt].max); num[cnt].min=num[cnt].max; return; } build(left, mid, cnt*2); build(mid+1, right, cnt*2+1); num[cnt].max=MAX(num[cnt*2].max, num[cnt*2+1].max); num[cnt].min=MIN(num[cnt*2].min, num[cnt*2+1].min); } void query(int left, int right, int cnt) { int mid; if(num[cnt].left==left&&num[cnt].right==right) { Max=MAX(Max, num[cnt].max); Min=MIN(Min, num[cnt].min); return; } mid=(num[cnt].left+num[cnt].right)>>1; if(right<=mid) query(left, right, cnt*2); else if(left>mid) query(left, right, cnt*2+1); else { query(left, mid, cnt*2); query(mid+1, right, cnt*2+1); } } int main() { int n, m, b, d; // char s[10]; scanf("%d%d", &n, &m); build(1, n, 1); while(m--) { scanf("%d%d", &b, &d); Max=0; Min=INF; query(b, d, 1); printf("%d\n", Max-Min); } return 0; }
4、
区间更新, 单点查询
#include <cstdio> #define N 1000001 struct node { int l, r, c; }num[N*3]; void build(int o, int l, int r) { num[o].l=l; num[o].r=r; num[o].c=0; if(l<r) { int mid=(l+r)>>1; build(o<<1, l, mid); build(o<<1|1, mid+1, r); } } void pushDown(int o) { if(num[o].c) { num[o<<1].c+=num[o].c; num[o<<1|1].c+=num[o].c; num[o].c=0; } } void update(int o, int l, int r, int c) { if(num[o].l==l&&num[o].r==r) { num[o].c+=c; return; } int mid=(num[o].l+num[o].r)>>1; if(r<=mid) update(o<<1, l, r, c); else if(l>mid) update(o<<1|1, l, r, c); else { update(o<<1, l, mid, c); update(o<<1|1, mid+1, r, c); } } int query(int o, int id) { if(num[o].l==num[o].r) return num[o].c; int mid=(num[o].l+num[o].r)>>1; int ans=num[o].c; if(id<=mid) ans+=query(o<<1, id); else ans+=query(o<<1|1, id); return ans; /*if(num[o].l<num[o].r) { pushDown(o); int mid=(num[o].l+num[o].r)>>1; if(id<=mid) return query(o<<1, id); else return query(o<<1|1, id); }*/ return num[o].c; } int main() { int n, m, a, b, c; char op[10]; scanf("%d%d", &n, &m); build(1, 1, m); while(n--) { scanf("%s", op); if(op[0]=='A') { scanf("%d%d%d", &a, &b, &c); if(!a) a++; update(1, a, b, c); } else { scanf("%d", &a); printf("%d\n", query(1, a)); } } return 0; }
浙公网安备 33010602011771号