热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【北大夏令营笔记-线段树】POJ3468-ASimpleProblemwithIntegers

ASimpleProblemwithIntegersTimeLimit:5000MSMemoryLimit:131072KTotalSubmissions:57993Accep
A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072K
Total Submissions: 57993 Accepted: 17658
Case Time Limit: 2000MS
Description

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output

4
55
9
15
Hint

The sums may exceed the range of 32-bit integers.
Source

POJ Monthly--2007.11.25, Yang Yi






AC代码:

#include
using namespace std;
struct CNode
{
int L,R;
CNode *pLeft,*pRight;
long long nSum;//原来的和
long long lnc;//增量c的累加
};
CNode Tree[200010];//两倍叶子节点数目就足够
int nCount=0;
int Mid(CNode *pRoot)
{
return (pRoot->L+pRoot->R)/2;
}
void BuildTree(CNode *pRoot,int L,int R)
{
pRoot->L=L;
pRoot->R=R;
pRoot->nSum=0;
pRoot->lnc=0;
if(L==R)
return;
nCount++;
pRoot->pLeft=Tree+nCount;
nCount++;
pRoot->pRight=Tree+nCount;
BuildTree(pRoot->pLeft,L,(L+R)/2);
BuildTree(pRoot->pRight,(L+R)/2+1,R);
}
void Insert(CNode *pRoot,int i,int v)
{
if(pRoot->L==i&&pRoot->R==i)
{
pRoot->nSum=v;
return;
}

pRoot->nSum+=v;
if(i<=Mid(pRoot))
Insert(pRoot->pLeft,i,v);
else
Insert(pRoot->pRight,i,v);
}
//添加的规律:找到终节点前计算(或更新)nSum,仅在终结点(完全属于所加区间的节点)加c
//即是,更新nSum的没有更新C(但nSum是更新后的值),更新C的没有更新nSum;
void Add(CNode *pRoot,int a,int b,long long c)
{
if(pRoot->L==a&&pRoot->R==b)
{
pRoot->lnc+=c;
return;
}
pRoot->nSum+=c*(b-a+1);
if(b<=(pRoot->L+pRoot->R)/2)
Add(pRoot->pLeft,a,b,c);
else if(a>=(pRoot->L+pRoot->R)/2+1)
Add(pRoot->pRight,a,b,c);
else
{
Add(pRoot->pLeft,a,(pRoot->L+pRoot->R)/2,c);
Add(pRoot->pRight,(pRoot->L+pRoot->R)/2+1,b,c);
}
}
long long QuerynSum(CNode *pRoot,int a,int b)
{
if(pRoot->L==a&&pRoot->R==b)
{
//终节点仅计算和,不对c进行下一级更新
return pRoot->nSum+(pRoot->R-pRoot->L+1)*pRoot->lnc;
}
//算好非终节点的nSum之后,更新后面的增量c,将本节点的增量清0
pRoot->nSum+=(pRoot->R-pRoot->L+1)*pRoot->lnc;
Add(pRoot->pLeft,pRoot->L,Mid(pRoot),pRoot->lnc);
Add(pRoot->pRight,Mid(pRoot)+1,pRoot->R,pRoot->lnc);
pRoot->lnc=0;

if(b<=Mid(pRoot))
return QuerynSum(pRoot->pLeft,a,b);
else if(a>=Mid(pRoot)+1)
return QuerynSum(pRoot->pRight,a,b);
else{
return QuerynSum(pRoot->pLeft,a,Mid(pRoot))+
QuerynSum(pRoot->pRight,Mid(pRoot)+1,b);
}
}
int main()
{
int n,q,a,b,c;
char cmd[10];
scanf("%d %d",&n,&q);
int i,j,k;
nCount=0;
BuildTree(Tree,1,n);
for(i=1;i<=n;i++)
{
scanf("%d",&a);
Insert(Tree,i,a);
}
for(i=0;i {
scanf("%s",cmd);
if(cmd[0]=='C'){
scanf("%d%d%d",&a,&b,&c);
Add(Tree,a,b,c);
}
else
{
scanf("%d%d",&a,&b);
printf("%I64d\n",QuerynSum(Tree,a,b));
}
}
return 0;
}


推荐阅读
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Python语法上的区别及注意事项
    本文介绍了Python2x和Python3x在语法上的区别,包括print语句的变化、除法运算结果的不同、raw_input函数的替代、class写法的变化等。同时还介绍了Python脚本的解释程序的指定方法,以及在不同版本的Python中如何执行脚本。对于想要学习Python的人来说,本文提供了一些注意事项和技巧。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • 《2017年3月全国计算机等级考试二级C语言上机题库完全版》由会员分享,可在线阅读,更多相关《2017年3月全国计算机等级考试二级C语言上机题库完全版( ... [详细]
  • C语言自带的快排和二分查找
    Author🚹:CofCaiEmail✉️:cai.dongjunnexuslink.cnQQ😙:1664866311personalPage&#x ... [详细]
  • 本文介绍了C++中的引用运算符及其应用。引用运算符是一种将变量定义为另一个变量的引用变量的方式,在改变其中一个变量时,两者均会同步变化。引用变量来源于数学,在计算机语言中用于储存计算结果或表示值抽象概念。变量可以通过变量名访问,在指令式语言中引用变量通常是可变的,但在纯函数式语言中可能是不可变的。本文还介绍了引用变量的示例及验证,以及引用变量在函数形参中的应用。当定义的函数使用引用型形参时,函数调用时形参的改变会同时带来实参的改变。 ... [详细]
  • tcpdump 4.5.1 crash 深入分析
    tcpdump 4.5.1 crash 深入分析 ... [详细]
author-avatar
米粒多可爱几_642
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有