Splay树(区间更新)—— POJ 3468 A Simple Problem with Integers

2024-09-05 04:08

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

对应POJ 题目:点击打开链接

A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072K
Total Submissions: 72765 Accepted: 22465
Case Time Limit: 2000MS

Description

You have N integers, A1A2, ... , 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 A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+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.

题意:

输入n,m;表示有n个数和m个询问。接着输入每个数的初始值。接着每个询问表示:Q表示求解i,j区间的和,C表示i~j区间的每个值都+k

思路:

Splay树区间更新问题,注意在更新标记后向上更新。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX(x, y) ((x) > (y) ? (x) : (y))typedef struct TREE
{long long sum; //以该结点为根的树的元素和TREE *fa, *l, *r;int sz; //以该结点为根的树的总结点数int add; //懒惰标记
}Tree;void Push_down(Tree *T)
{if(NULL == T) return;if(T->add){T->sum += ((long long)(T->sz) * T->add);if(T->l) T->l->add += T->add;if(T->r) T->r->add += T->add;T->add = 0;}
}void Init(Tree *&T, int n)
{int i;long long a;Tree *cur, *pre;pre = (Tree *)malloc(sizeof(Tree));pre->sum = 0;pre->fa = pre->l = pre->r = NULL;pre->sz = 1;pre->add = 0;for(i = n - 1; i > -1; i--){cur = (Tree *)malloc(sizeof(Tree));scanf("%I64d", &a);cur->l = pre;cur->r = NULL;pre->fa = cur;cur->sz = pre->sz + 1;cur->sum = a + pre->sum;cur->add = 0;pre = cur;if(0 == i){cur = (Tree *)malloc(sizeof(Tree));cur->fa = NULL;cur->l = pre;cur->r = NULL;pre->fa = cur;cur->sz = pre->sz + 1;cur->sum = pre->sum;cur->add = 0;}}T = cur;
}void R_rotate(Tree *x)
{Tree *y = x->fa;Tree *z = y->fa;Tree *k = x->r;int sx = x->sz, sy = y->sz, sk = 0;long long sumx = x->sum, sumy = y->sum, sumk = 0;if(k){Push_down(k);sk = k->sz;sumk = k->sum;}y->l = k;x->r = y;if(z){if(y == z->l) z->l = x;else z->r = x;}if(k) k->fa = y;y->fa = x;x->fa = z;y->sz = sy - sx + sk;x->sz = sx - sk + y->sz;y->sum = sumy - sumx + sumk;x->sum = sumx - sumk + y->sum;
}void L_rotate(Tree *x)
{Tree *y = x->fa;Tree *z = y->fa;Tree *k = x->l;int sx = x->sz, sy = y->sz, sk = 0;long long sumx = x->sum, sumy = y->sum, sumk = 0;if(k){Push_down(k);sk = k->sz;sumk = k->sum;}y->r = k;x->l = y;if(z){if(y == z->r) z->r = x;else z->l = x;}if(k) k->fa = y;y->fa = x;x->fa = z;y->sz = sy - sx + sk;x->sz = sx - sk + y->sz;y->sum = sumy - sumx + sumk;x->sum = sumx - sumk + y->sum;
}//寻找第x个数的结点
Tree *FindTag(Tree *T, int x)
{if(NULL == T) return NULL;Push_down(T);Tree *p;p = T;int sum = (p->l ? p->l->sz : 0) + 1;while(sum != x && p){if(sum < x){p = p->r;x -= sum;}else p = p->l;Push_down(p);sum = (p->l ? p->l->sz : 0) + 1;}return p;
}void Splay(int x, Tree *&T)
{Push_down(T);Tree *p, *X, *end, *new_t;end = T->fa;new_t = T;if(end) new_t = T->fa;X = FindTag(new_t, x);while(X->fa != end){p = X->fa;if(end == p->fa){ //p是根结点if(X == p->l) R_rotate(X);else L_rotate(X);break;}//p不是根结点if(X == p->l){if(p == p->fa->l){R_rotate(p); //LLR_rotate(X); //LL}else{R_rotate(X); //RLL_rotate(X);}}else{if(p == p->fa->r){ //RRL_rotate(p);L_rotate(X);}else{ //LRL_rotate(X);R_rotate(X);}}}T = X;
}void FreeTree(Tree *T)
{if(NULL == T) return;FreeTree(T->l);FreeTree(T->r);free(T);
}void InOrder(Tree *T)
{if(NULL == T) return;Push_down(T);InOrder(T->l);printf("%d ", T->sum);InOrder(T->r);
}int main()
{//freopen("in.txt", "r", stdin);Tree *T;T = NULL;int n, q;int a, b, c;char s[3];scanf("%d%d", &n, &q);Init(T, n);while(q--){//InOrder(T);//printf("\n");scanf("%s", s);if('Q' == s[0]){scanf("%d%d", &a, &b);a++; b++;Splay(a - 1, T);Splay(b + 1, T->r);Push_down(T->r->l);printf("%I64d\n", T->r->l->sum);}else{scanf("%d%d%d", &a, &b, &c);a++; b++;Splay(a - 1, T);Splay(b + 1, T->r);T->r->l->add += c;//向上更新T->r->sum += ((long long)(b - a + 1) * c);T->sum += ((long long)(b - a + 1) * c);}}FreeTree(T);return 0;
}
















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



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

相关文章

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

linux安装、更新、卸载anaconda实践

《linux安装、更新、卸载anaconda实践》Anaconda是基于conda的科学计算环境,集成1400+包及依赖,安装需下载脚本、接受协议、设置路径、配置环境变量,更新与卸载通过conda命令... 目录随意找一个目录下载安装脚本检查许可证协议,ENTER就可以安装完毕之后激活anaconda安装更

Nginx进行平滑升级的实战指南(不中断服务版本更新)

《Nginx进行平滑升级的实战指南(不中断服务版本更新)》Nginx的平滑升级(也称为热升级)是一种在不停止服务的情况下更新Nginx版本或添加模块的方法,这种升级方式确保了服务的高可用性,避免了因升... 目录一.下载并编译新版Nginx1.下载解压2.编译二.替换可执行文件,并平滑升级1.替换可执行文件

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

MySQL追踪数据库表更新操作来源的全面指南

《MySQL追踪数据库表更新操作来源的全面指南》本文将以一个具体问题为例,如何监测哪个IP来源对数据库表statistics_test进行了UPDATE操作,文内探讨了多种方法,并提供了详细的代码... 目录引言1. 为什么需要监控数据库更新操作2. 方法1:启用数据库审计日志(1)mysql/mariad

Oracle 通过 ROWID 批量更新表的方法

《Oracle通过ROWID批量更新表的方法》在Oracle数据库中,使用ROWID进行批量更新是一种高效的更新方法,因为它直接定位到物理行位置,避免了通过索引查找的开销,下面给大家介绍Orac... 目录oracle 通过 ROWID 批量更新表ROWID 基本概念性能优化建议性能UoTrFPH优化建议注

Redis中6种缓存更新策略详解

《Redis中6种缓存更新策略详解》Redis作为一款高性能的内存数据库,已经成为缓存层的首选解决方案,然而,使用缓存时最大的挑战在于保证缓存数据与底层数据源的一致性,本文将介绍Redis中6种缓存更... 目录引言策略一:Cache-Aside(旁路缓存)策略工作原理代码示例优缺点分析适用场景策略二:Re

Pandas利用主表更新子表指定列小技巧

《Pandas利用主表更新子表指定列小技巧》本文主要介绍了Pandas利用主表更新子表指定列小技巧,通过创建主表和子表的DataFrame对象,并使用映射字典进行数据关联和更新,实现了从主表到子表的同... 目录一、前言二、基本案例1. 创建主表数据2. 创建映射字典3. 创建子表数据4. 更新子表的 zb

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -