POJ 3468 A Simple Problem with Integers (线段树区间更新模板)

2024-02-07 17:48

本文主要是介绍POJ 3468 A Simple Problem with Integers (线段树区间更新模板),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

POJ 3468

老是忘。。


#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
typedef long long ll;
struct node  {int l, r, m;ll val, mark;	//注意此处标记和值都要定义为long long 
};
const int MAXN = 100100;
node T[MAXN * 4 + 10];
ll a[MAXN];
void build(int root, int begin, int end) {T[root].mark = 0;T[root].l = begin;T[root].r = end;T[root].m = (begin + end) >> 1;if(begin == end) {T[root].val = a[begin];}else {build(root << 1, begin, T[root].m);build(root << 1 | 1, T[root].m + 1, end);T[root].val = T[root << 1].val + T[root << 1 | 1].val;}
}
ll query(int root, int l, int r) {if(T[root].l == l && T[root].r == r) {return T[root].val + T[root].mark * (r - l + 1);}else {if(T[root].mark != 0) {T[root << 1].mark += T[root].mark;T[root << 1 | 1].mark += T[root].mark;T[root].val += T[root].mark * (T[root].r - T[root].l + 1);T[root].mark = 0;}if(r <= T[root].m) return query(root << 1, l, r);else if(l > T[root].m) return query(root << 1 | 1, l, r);else return query(root << 1, l, T[root].m) + query(root << 1 | 1, T[root].m + 1, r);}
}
void updata(int root, int l, int r, int add) {if(T[root].l == l && T[root].r == r) {T[root].mark += add;}else {T[root].val += add * (r - l + 1);if(r <= T[root].m) updata(root << 1, l, r, add);else if(l > T[root].m) updata(root << 1 | 1, l, r, add);else {updata(root << 1, l, T[root].m, add);updata(root << 1 | 1, T[root].m + 1, r, add);}}
}
int main() {int n, q;while(~scanf("%d %d", &n, &q)) {int i;for(i = 1; i <= n; i++) {scanf("%I64d", a + i);}getchar();build(1, 1, n);char ch;int l, r, add;for(i = 0; i < q; i++) {scanf("%c %d %d", &ch, &l, &r);getchar();if(ch == 'Q') {printf("%I64d\n", query(1, l, r));}if(ch == 'C') {scanf("%d", &add);getchar();updata(1, l, r, add);}}}return 0;
}

另附一个线段树模板:

#include<stdio.h>
#include<algorithm>
#include<string.h>
#define ll __int64
#define M 100007
using namespace std;
struct node
{ll l,r,mid,val,mark;
}tree[M<<2];
ll s[M];
void build(ll left,ll right,ll i)//建树
{tree[i].l=left;tree[i].r=right;tree[i].mid=(left+right)>>1;tree[i].mark=0;if(left==right){tree[i].val=s[left]; return;}build(left,tree[i].mid,i*2);build(tree[i].mid+1,right,i*2+1);tree[i].val=tree[i*2].val+tree[i*2+1].val;
}
void update(int pos,ll val,int i)//点更新
{tree[i].val+=val;if(tree[i].l==tree[i].r)return;if(pos<=tree[i].mid)update(pos,val,i*2);else update(pos,val,i*2+1);
}
//ll query(int left,int right,int i)//点查询
//{
//    if(tree[i].l==left&&tree[i].r==right)return tree[i].val;
//    if(right<=tree[i].mid)query(left,right,i*2);
//    else if(left>tree[i].mid)query(left,right,i*2+1);
//    else return query(left,tree[i].mid,i*2)+query(tree[i].mid+1,right,i*2+1);
//}
void update(int left,int right,ll val,int i)//区间更新
{if(tree[i].l==left&&tree[i].r==right){tree[i].mark+=val;return;}tree[i].val+=val*(right-left+1);if(tree[i].mid<left)update(left,right,val,2*i+1);else if(tree[i].mid>=right)update(left,right,val,2*i);else{update(left,tree[i].mid,val,2*i);update(tree[i].mid+1,right,val,2*i+1);}
}
ll query(int left,int right,int i)//区间查询
{if(tree[i].l==left&&tree[i].r==right)  return tree[i].val+tree[i].mark*(right-left+1);if(tree[i].mark!=0){tree[i*2].mark+=tree[i].mark;tree[i*2+1].mark+=tree[i].mark;tree[i].val+=(tree[i].r-tree[i].l+1)*tree[i].mark;tree[i].mark=0;}if(tree[i].mid>=right){return query(left,right,i*2);}else if(tree[i].mid<left){return query(left,right,i*2+1);}else{return query(left,tree[i].mid,i*2)+query(tree[i].mid+1,right,i*2+1);}
}
int main()
{ll n,m,i,j,k;ll l,f,num;char str[5];while(scanf("%I64d%I64d",&n,&m)!=EOF){for(int i=1;i<=n;i++)scanf("%I64d",&s[i]);build(0,n,1);for(i=0;i<m;i++){//  printf("i=%I64d",i);scanf("%s",&str);if(str[0]=='Q'){scanf("%I64d%I64d",&l,&f);printf("%I64d\n",query(l,f,1));}if(str[0]=='C'){scanf("%I64d%I64d%I64d",&l,&f,&num);update(l,f,num,1);}}}return 0;
}


这篇关于POJ 3468 A Simple Problem with Integers (线段树区间更新模板)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/688471

相关文章

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

一文详解SQL Server如何跟踪自动统计信息更新

《一文详解SQLServer如何跟踪自动统计信息更新》SQLServer数据库中,我们都清楚统计信息对于优化器来说非常重要,所以本文就来和大家简单聊一聊SQLServer如何跟踪自动统计信息更新吧... SQL Server数据库中,我们都清楚统计信息对于优化器来说非常重要。一般情况下,我们会开启"自动更新

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

基于Java实现模板填充Word

《基于Java实现模板填充Word》这篇文章主要为大家详细介绍了如何用Java实现按产品经理提供的Word模板填充数据,并以word或pdf形式导出,有需要的小伙伴可以参考一下... Java实现按模板填充wor编程d本文讲解的需求是:我们需要把数据库中的某些数据按照 产品经理提供的 word模板,把数据

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Ubuntu 24.04 LTS怎么关闭 Ubuntu Pro 更新提示弹窗?

《Ubuntu24.04LTS怎么关闭UbuntuPro更新提示弹窗?》Ubuntu每次开机都会弹窗提示安全更新,设置里最多只能取消自动下载,自动更新,但无法做到直接让自动更新的弹窗不出现,... 如果你正在使用 Ubuntu 24.04 LTS,可能会注意到——在使用「软件更新器」或运行 APT 命令时,

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,