【线段树基础】NKOJ 1321 数列操作

时间限制 : 10000 MS   空间限制 : 165536 KB
问题描述

假设有一列数{Ai}(1≤i≤n),支持如下两种操作:
将Ak的值加D。(k, D是输入的数)
输出As+As+1+…+At。(s, t都是输入的数,S≤T)

输入格式

第一行一个整数n,
第二行为n个整数,表示{Ai}的初始值≤10000。
第三行为一个整数m,表示操作数
下接m行,每行描述一个操作,有如下两种情况:
ADD k d (表示将Ak加d,1<=k<=n,d为数,d的绝对值不超过10000)
SUM s t (表示输出As+…+At)

输出格式

对于每一个SUM提问,输出结果

样例输入 1


1 2 3 2 4 

SUM 1 2
SUM 1 5
ADD 1 2
SUM 1 2
SUM 1 5

样例输出 1


12 

14

样例输入 2

10
44 37 20 29 13 8 32 14 46 29 
8
ADD 5 3
SUM 1 8
SUM 4 6
ADD 3 18
SUM 2 5
ADD 4 15
SUM 1 7
SUM 5 10

样例输出 2

200
53
120
219
145

提示

M,N<=100000

【提示】

线段树板题

【参考代码】

 1 #include<cstdio>
 2 #define maxn 100003
 3 int n, m;
 4 int A[maxn];
 5 char op[3];
 6 struct node {
 7     int a, b, v;
 8 }Tree[maxn << 2];
 9 namespace Ironclad_Programming {
10     #define R register int
11     #define For(i, s, n) for (R i = s; i <= n; ++ i)
12     namespace ini {
13         void MakeTree(int p, int x, int y) {
14             Tree[p].a = x;
15             Tree[p].b = y;
16             if (x < y) {
17                 MakeTree(p * 2, x, ((x + y) >> 1));
18                 MakeTree(p * 2 + 1, ((x + y) >> 1) + 1, y);
19                 Tree[p].v = Tree[p * 2].v + Tree[p * 2 + 1].v;
20             } else Tree[p].v = A[x];
21         }
22         void executive() {
23             scanf("%d", &n);
24             For (i, 1, n)scanf("%d", &A[i]);
25             MakeTree(1, 1, n);
26         }
27     }
28     namespace solve {
29         void Add(int p, int k, int d) {
30             Tree[p].v += d;
31             if (Tree[p].a == Tree[p].b)return;
32             if (Tree[p * 2].a <= k && Tree[p * 2].b >= k)Add(p * 2, k, d);
33             if (Tree[p * 2 + 1].a <= k && Tree[p * 2 + 1].b >= k)Add(p * 2 + 1, k, d);
34         }
35         int GetSum(int p, int s, int t) {
36             if (t < Tree[p].a || s > Tree[p].b)return 0;
37             if (s <= Tree[p].a && Tree[p].b <= t)return Tree[p].v;
38             else {
39                 int Total = 0;
40                 Total += GetSum(p * 2, s, t);
41                 Total += GetSum(p * 2 + 1, s, t);
42                 return Total;
43             }
44         }
45         void executive() {
46             scanf("%d", &m);
47             For (i, 1, m) {
48                 scanf("%s", op);
49                 if (op[0] == ‘A‘) {
50                     int k, d;
51                     scanf("%d%d", &k, &d);
52                     Add(1, k, d);
53                 } else {
54                     int s, t;
55                     scanf("%d%d", &s, &t);
56                     printf("%d\n", GetSum(1, s, t));
57                 }
58             }
59         }
60     }
61     void Main() {
62         ini::executive();
63         solve::executive();
64     }
65     #undef R
66     #undef For
67 }
68 int main() {
69     Ironclad_Programming::Main();
70     return 0;
71 }

原文地址:https://www.cnblogs.com/Limbo-To-Heaven/p/11656403.html

时间: 2024-10-19 01:50:01

【线段树基础】NKOJ 1321 数列操作的相关文章

线段树基础知识----(基础数据结构)--(一)

1.定义 引入:为什么要使用线段树而不用数组模拟呢? answer:因为有些题用数组来做就要超时,用线段树的O(log(n))的时间复杂度刚好可以求解 毫无疑问线段树是一种数据结构,但是它实际是一个类似树状的链表结构(个人认为) ///还是要正经一点(照搬教科书)----------- / ////////////////////////////////////////////////////////////////////// 线段树定义:线段树是一种二叉搜索树,与区间树相似,它将一个区间划分

线段树 基础单点更新 敌兵布阵

题:敌兵布阵 标准线段树模板代码: #include<cstdio> #include<cstring> const int maxn = 500000 + 10; struct Node{ int left, right, count; }node[maxn]; int a[maxn]; /*********************************** ***************建树**************** ************i是区间序号********

线段树基础

关于线段树的原理学习,可以参看杨弋大牛的论文<线段树>以及刘汝佳老师的<算法竞赛入门经典(训练指南)>,代码风格学习hzwer或者notonlysuccess均可. 一.单点更新 最基础的线段树 题目:codevs1080 链接:http://codevs.cn/problem/1080/ 分析:最简单的线段树,单点更新,区间求和 1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4

[JSOI2008]最大数(线段树基础)

题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制: L 不超过当前数列的长度.(L > 0) 2. 插入操作. 语法:A n 功能:将 n 加上 t ,其中 t 是最近一次查询操作的答案(如果还未执行过查询操作,则 t=0 ),并将所得结果对一个固定的常数 D  取模,将所得答案插入到数列的末尾. 限制: n 是整数(可能为负数)并且在长整范围内. 注意:初始时数列是空的,没有一个数.

HDU 1754--I Hate It(线段树基础)

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 44820    Accepted Submission(s): 17591 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感.不管你喜不喜欢,现在需要你做的是,就是按照老师的

最大最小值(线段树基础版)

最大最小值 时间限制:1000 ms  |  内存限制:65535 KB 描述 给出N个整数,执行M次询问. 对于每次询问,首先输入三个整数C.L.R: 如果C等于1,输出第L个数到第R个数之间的最小值: 如果C等于2,输出第L个数到第R个数之间的最大值: 如果C等于3,输出第L个数到第R个数之间的最小值与最大值的和. (包括第L个数和第R个数). 输入 首先输入一个整数T(T≤100),表示有T组数据. 对于每组数据,先输入一个整数N(1≤N≤10000),表示有N个整数: 接下来一行有N个整

POJ2528线段树基础

开始就直接用延迟标记搞了下,最后发现内存肯定会爆了,数据太大了: 问了瓜神,原来应该用离散化来做这题,具体见注释 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #in

I Hate It(线段树基础)

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 45287    Accepted Submission(s): 17773 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟

Balanced Lineup---poj3264线段树基础

题目链接 求对应区间最大值与最小值的差: #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #define INF 0xfffffff #define N 50010 using namespace std; #define Lson r<<1 #define Rson r<<1|1 struct SegTree { int L, R