线段树维护更多类型的信息

news2024/11/15 21:52:09

P3870 [TJOI2009] 开关 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

sum维护一段区域的和;revers记录翻转懒信息;

lazy:灯泡翻转后个数就是之前不亮的个数,revers变为原来的反

#include <iostream>
using namespace std;
const int maxn = 100001;
int sum[maxn<<2];
bool revers[maxn << 2];
void up(int i) {
	sum[i] = sum[i << 1] + sum[i << 1 | 1];
}
void lazy(int i, int n) {
	sum[i] = n - sum[i];
	revers[i] = !revers[i];
}
void down(int i, int ln, int rn) {
	if (revers[i]) {
		lazy(i << 1, ln);
		lazy(i << 1 | 1, rn);
		revers[i] = false;
	}
}
void reverse(int jobl,int jobr,int l,int r,int i) {
	if (jobl <= l && jobr >= r)
		lazy(i, r - l + 1);
	else {
		int mid = l + ((r - l) >> 1);
		down(i, mid - l + 1, r - mid);
		if (jobl <= mid)
			reverse(jobl, jobr, l, mid, i << 1);
		if (jobr > mid)
			reverse(jobl, jobr, mid + 1, r, i << 1 | 1);
		up(i);
	}
}
int query(int jobl, int jobr, int l, int r, int i) {
	if (jobl <= l && jobr >= r)
		return sum[i];
	else {
		int mid = l + ((r - l) >> 1);
		down(i, mid - l + 1, r - mid);
		int ans = 0;
		if (jobl <= mid)
			ans += query(jobl, jobr, l, mid, i << 1);
		if (jobr > mid)
			ans += query(jobl, jobr, mid + 1, r, i << 1 | 1);
		return ans;
	}
}
void build(int l, int r, int i) {
	if (l == r) sum[i] = 0;
	else {
		int mid = l + ((r - l) >> 1);
		build(l, mid, i << 1);
		build(mid + 1, r, i << 1 | 1);
		up(i);
	}
	revers[i] = false;
}
int main() {
	int n, m;
	cin >> n >> m;
	int a, b, c;
	int rem[maxn];
	int size = 0;
	build(1, n, 1);
	while (m--) {
		cin >> a >> b >> c;
		if (a == 0) {
			reverse(b, c, 1, n, 1);
		}
		else {
			rem[size++]=query(b, c, 1, n, 1);
		}
	}
	for (int i = 0; i < size; i++)
		cout << rem[i] << endl;
	return 0;
}

P2184 贪婪大陆 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

此题如果一段区域内不同的地雷总数是不能作为线段树信息维护的;所以此题维护的是一段区域内以某种地雷开头的位置数量和以某种地雷结尾的位置的数量两种信息。那么求一段区域 l - r 内地雷的总数,从1 - r地雷的开头数减去1 - l-1地雷的结尾数就是地雷的种类数。

此题是单点增加,所以不需要down和lazy操作

#include <iostream>
#include <vector>
using namespace std;
const int maxn = 100001;
int bomstart[maxn << 2];
int bomends[maxn << 2];
void up(int i) {
	bomstart[i] = bomstart[i << 1] + bomstart[i << 1 | 1];
	bomends[i] = bomends[i << 1] + bomends[i << 1 | 1];
}
void add(int jobt, int jobi, int l, int r, int i) {
	if (l == r) {
		if (jobt == 0)
			bomstart[i]++;
		else
			bomends[i]++;
	}
	else {
		int mid = l + ((r - l) >> 1);
		if (mid >= jobi)
			add(jobt, jobi, l, mid, i << 1);
		else
			add(jobt, jobi, mid + 1, r, i << 1 | 1);
		up(i);
	}
}
int query(int jobt,int jobl, int jobr, int l, int r, int i) {
	if (jobl <= l && jobr >= r)
		return jobt == 0 ? bomstart[i] : bomends[i];
	else {
		int mid = l + ((r - l) >> 1);
		int ans = 0;
		if (mid >= jobl)
			ans += query(jobt, jobl, jobr, l, mid, i << 1);
		if (jobr > mid)
			ans += query(jobt, jobl, jobr,mid + 1, r, i << 1 | 1);
		return ans;
	}
}
void build(int l, int r, int i) {
	if (l < r) {
		int mid = l + ((r - l) >> 1);
		build(l, mid, i << 1);
		build(mid + 1, r, i << 1 | 1);
	}
	bomends[i] = 0;
	bomstart[i] = 0;
}
int main() {
	int n, m;
	cin >> n >> m;
	int a, b, c;
	vector<int>rem;
	while (m--) {
		cin >> a >> b >> c;
		if (a == 1) {
			add(0, b, 1, n, 1);
			add(1, c, 1, n, 1);
		}
		else {
			int s = query(0, 1, c, 1, n, 1);
			int e =b==1?0: query(1, 1, b-1, 1, n, 1);
			rem.push_back(s - e);
		}
	}
	for (auto i : rem)
		cout << i << endl;
	return 0;

}

 P1438 无聊的数列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

如果知道一组数的差分数组,在原数组的l - r范围上增加首项为k,公差为d的等差数组,只需要在l上增加k,l+1到r上增加d,r+1减去末项,从1到p求和即可得出原数组操作后p位置上的数。所以对差分信息维护线段树,做add操作和query操作即可

#include <iostream>
using namespace std;
const int maxn = 100001;
int diff[maxn];
long sum[maxn << 2];
long add[maxn << 2];
void up(int i) {
	sum[i] = sum[i << 1] + sum[i << 1 | 1];
}
void lazy(int i, int  n, int v) {
	add[i] += v;
	sum[i] += v * n;
}
void down(int i, int ln, int rn) {
	if (add[i] != 0) {
		lazy(i << 1, ln, add[i]);
		lazy(i << 1 | 1, rn, add[i]);
		add[i] = 0;
	}
}
void build(int l, int r, int i) {
	if (l == r)
		sum[i] = diff[l];
	else {
		int mid = l + ((r - l) >> 1);
		build(l, mid, i << 1);
		build(mid + 1, r, i << 1 | 1);
		up(i);
	}
	add[i] = 0;
}
void add1(int jobl, int jobr, int jobv, int l, int r, int i) {
	if (jobl <= l && jobr >= r) {
		lazy(i, r - l + 1, jobv);
	}
	else {
		int mid = l + ((r - l) >> 1);
		down(i, mid - l + 1, r - mid);
		if(mid>=jobl)
		add1(jobl, jobr, jobv, l, mid, i << 1);
		if(mid<jobr)
		add1(jobl, jobr, jobv, mid + 1, r, i << 1 | 1);
		up(i);
	}
}
long query(int jobl, int jobr, int l, int r, int i) {
	if (jobl <= l && jobr >= r)
		return sum[i];
	else {
		int mid = l + ((r - l) >> 1);
		long ans = 0;
		down(i, mid - l + 1, r - mid);
		if (jobl <= mid)
			ans += query(jobl, jobr, l, mid, i << 1);
		if (jobr > mid)
			ans += query(jobl, jobr, mid + 1, r, i << 1 | 1);
		return ans;
	}
}
int main() {
	int n, m;
	cin >> n >> m;
	int a;
	for (int i = 1,pre=0; i <= n; i++) {
		cin >> a;
		diff[i] = a - pre;
		pre = a;
	}
	build(1, n, 1);
	int b;
	int l, r, k, d;
	while (m--) {
		cin >> b;
		if (b == 1) {
			cin >> l >> r >> k >> d;
			int e = k + (r - l) * d;
			add1(l, l, k, 1, n, 1);
			if (l + 1 <= r)
				add1(l + 1, r, d, 1, n, 1);
			if (r < n)
				add1(r + 1, r + 1, -e, 1, n, 1);
		}
		else {
			int p;
			cin >> p;
			cout << query(1, p, 1, n, 1)<<endl;
		}
	}
	return 0;
}

P1471 方差 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

若求平均数和方差,只需要维护好累加和数组和平方和数组即可:累加和和平方和都可以成为线段树的维护信息。

add操作:累加和容易修改;平方和根据分析也可以O(1)修改

方差:拆开方差公式,用累加和和平方和就可以求出 

#include <cstdio>
using namespace std;

const int MAXN = 100001;

double arr[MAXN];
double sum1[MAXN << 2];
double sum2[MAXN << 2];
double addv[MAXN << 2];

void up(int i) {
    sum1[i] = sum1[i << 1] + sum1[i << 1 | 1];
    sum2[i] = sum2[i << 1] + sum2[i << 1 | 1];
}

void lazy(int i, double v, int n) {
    sum2[i] += sum1[i] * v * 2 + v * v * n;
    sum1[i] += v * n;
    addv[i] += v;
}

void down(int i, int ln, int rn) {
    if (addv[i] != 0) {
        lazy(i << 1, addv[i], ln);
        lazy(i << 1 | 1, addv[i], rn);
        addv[i] = 0;
    }
}

void build(int l, int r, int i) {
    if (l == r) {
        sum1[i] = arr[l];
        sum2[i] = arr[l] * arr[l];
    } else {
        int mid = (l + r) >> 1;
        build(l, mid, i << 1);
        build(mid + 1, r, i << 1 | 1);
        up(i);
    }
    addv[i] = 0;
}

void add(int jobl, int jobr, double jobv, int l, int r, int i) {
    if (jobl <= l && r <= jobr) {
        lazy(i, jobv, r - l + 1);
    } else {
        int mid = (l + r) >> 1;
        down(i, mid - l + 1, r - mid);
        if (jobl <= mid) {
            add(jobl, jobr, jobv, l, mid, i << 1);
        }
        if (jobr > mid) {
            add(jobl, jobr, jobv, mid + 1, r, i << 1 | 1);
        }
        up(i);
    }
}

double query(double *sum, int jobl, int jobr, int l, int r, int i) {
    if (jobl <= l && r <= jobr) {
        return sum[i];
    }
    int mid = (l + r) >> 1;
    down(i, mid - l + 1, r - mid);
    double ans = 0;
    if (jobl <= mid) {
        ans += query(sum, jobl, jobr, l, mid, i << 1);
    }
    if (jobr > mid) {
        ans += query(sum, jobl, jobr, mid + 1, r, i << 1 | 1);
    }
    return ans;
}

int main() {
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%lf", &arr[i]);
    }
    build(1, n, 1);
    for (int i = 1; i <= m; i++) {
        int op, jobl, jobr;
        scanf("%d", &op);
        if (op == 1) {
            double jobv;
            scanf("%d %d %lf", &jobl, &jobr, &jobv);
            add(jobl, jobr, jobv, 1, n, 1);
        } else if (op == 2) {
            scanf("%d %d", &jobl, &jobr);
            double ans = query(sum1, jobl, jobr, 1, n, 1) / (jobr - jobl + 1);
            printf("%.4f\n", ans);
        } else {
            scanf("%d %d", &jobl, &jobr);
            double a = query(sum1, jobl, jobr, 1, n, 1);
            double b = query(sum2, jobl, jobr, 1, n, 1);
            double size = jobr - jobl + 1;
            double ans = b / size - (a / size) * (a / size);
            printf("%.4f\n", ans);
        }
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2091065.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录第十九天 | 110.平衡二叉树,257. 二叉树的所有路径,404.左叶子之和,222. 完全二叉树的节点个数

110. 平衡二叉树 第一想法&#xff1a;首先要明确平衡二叉树的定义&#xff1f;左右节点的高度差不超过1&#xff1f;不会概念感觉无法下手... 返回参数返回int,为了标记已经不是平衡二叉树&#xff0c;用-1作标记 int traversal(TreeNode* root){if(rootnullptr) return 0;…

Linux_kernel烧写Uboot02

一、温故知新 1、开发环境 Ubuntu的Linux操作系统(18.04 20.04 22.04) 前面的版本号是双数&#xff0c;后面的版本号是04 lsb_release -a 用于查看系统版本号 uname -a 查看系统位数/内核版本号 2、体系架构 APP 各种控制界面\通…

数据库 变更和版本控制管理工具 --Bytebase 安装部署

数据库 变更和版本控制管理工具 --Bytebase 安装部署 文章目录 数据库 变更和版本控制管理工具 --Bytebase 安装部署前言一.Docker部署Bytebase1.Docker 配置2. pull 数据3. 执行部署4. 打开浏览器 部署完成 二、使用步骤1.注册超管2.配置 Configure External URL 总结 前言 B…

点餐收银小程序

一、项目概述 Hi&#xff0c;大家好&#xff0c;今天分享的项目是《点餐收银小程序》。 系统含管理员/商家/用户三种角色&#xff0c;商家能维护菜式类别、维护菜品信息&#xff0c;用户在小程序能够选择门店&#xff0c;查看门店下各个分类的菜式信息&#xff0c;并进行加购…

【vSphere 7/8】深入浅出 vSphere 证书 Ⅲ—— vSphere 证书的更新和替换概述

目录 摘要1. vSphere Certificate Architecture2. 证书更新和替换概述2.1更新 VMCA 签名的证书&#xff08;1&#xff09;使用 vSphere Client UI&#xff08;2&#xff09;使用 vSphere Certificate Manager 命令行工具&#xff08;自动&#xff09;&#xff08;3&#xff09;…

行业大模型元年,“有云处皆智能”的愿景还有多远?

打造新质生产力、推动高质量发展&#xff0c;已成为众多行业用户在数字经济时代的一道必答题。 今年《政府工作报告》就提出要深化大数据、人工智能等研发应用&#xff0c;开展“人工智能”行动&#xff0c;大力推进现代化产业体系建设&#xff0c;加快发展新质生产力。这其中…

IBM是中国IT界的黄埔军校

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 我第一次听说IBM还是小的时候&#xff0c;当时很多人都说IBM是厉害&#xff0c;外号“蓝色巨人”&#xff0c;潜移默化我也知道IBM牛了。 而且当年我买的第一款笔记本电脑就是IBM的ThinkPad系列&#xff0c;花了6…

Python酷库之旅-第三方库Pandas(112)

目录 一、用法精讲 491、pandas.DataFrame.cumsum方法 491-1、语法 491-2、参数 491-3、功能 491-4、返回值 491-5、说明 491-6、用法 491-6-1、数据准备 491-6-2、代码示例 491-6-3、结果输出 492、pandas.DataFrame.describe方法 492-1、语法 492-2、参数 492…

中国书法艺术孙溟㠭浅析《平复帖》

中国书法艺术孙溟㠭浅析《平复帖》 《平复帖》是西晋文学家、书法家陆机创作的书法作品&#xff0c;纵23.8厘米、横20.5厘米&#xff0c;共九行、八十四字&#xff0c;是陆机写给久病未愈朋友的问候信札&#xff0c;因其中有“恐难平复”字样&#xff0c;故得“平复帖”之名。 …

【C++ 面试 - STL】每日 3 题(一)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

2024最新最全:【计算机自学网站】大全,零基础入门到精通,看完这一篇就够了!

分享32个鲜为人知并且完全免费的高质量自学网站&#xff0c;每个都是堪称神器&#xff0c;让你相见恨晚。 1&#xff1a;Oeasy 是一个完全免费的综合视频教程网站&#xff0c;非常良心实用。 它提供的视频教程非常丰富并且质量很高&#xff0c;包括&#xff1a;PS 教程、手机…

通过 TS-Mixer 实现股票价格预测

作者:老余捞鱼 原创不易,转载请标明出处及原作者。 写在前面的话: 最近遇到了 Time Mixer 模型,该模型以在复杂数据集上提供令人印象深刻的结果而闻名。出于好奇,我决定将其应用于我在 Kaggle 上找到的数据集,其中包含 Microsoft 的历史股票价格。在本文中,我…

盘点免费且靠谱的AI大模型 API,统一封装,任性调用!

现在做大模型&#xff0c;还有靠谱且免费的 API 接口吗? 靠谱的不免费&#xff0c;免费的不靠谱&#xff0c;鱼和熊掌不可兼得&#xff1f; 非也&#xff01; 对于简单的指令而言&#xff0c;绝大部分免费的 LLM API 还是能打的&#xff0c;本文就给大家介绍几款&#xff0…

22.缓存雪崩缓存击穿

定义 同一时段大量的缓存key同时失效或者redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 解决方案 1.给不同key的TTL添加随机值。 2.利用redis集群提高服务的可用性。 3.给缓存业务添加降级限流策略。 4.给业务添加多级缓存。 缓存击穿 缓…

Redis持久化方式、常见问题及解决方案

在现代电商交易系统中&#xff0c;Redis作为一种高性能的内存数据库&#xff0c;被广泛用于缓存和数据持久化。然而&#xff0c;Redis作为内存数据库&#xff0c;面临着数据持久化和数据与持久化存储如MySQL之间的一致性问题。本文将详细讲解Redis的持久化方式、常见问题及其解…

常见框架报错信息

一、报错信息&#xff08;不同类型转换&#xff09; 2024-08-28 14:57:15.450 ERROR 8272 --- [io-8080-exec-12] c.w.common.exception.RRExceptionHandler : class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer ar…

IO进程练习:请在linux 利用c语言编程实现两个线程按照顺序依次输出”ABABABAB......“

例如&#xff1a;a线程输出”A”之后b线程输出”B”&#xff0c;然后a线程输出“A”&#xff0c;再b线程输出”B”&#xff0c;之后往复循环。 【1】使用信号量实现 代码展示&#xff1a; #include <stdio.h> #include <pthread.h> #include <string.h> #inc…

Java 输入与输出之 NIO.2【AIO】【Path、Paths、Files】【walkFileTree接口】探索之【三】

在JDK 1.7 版本中对NIO进行了完善&#xff0c;推出了NIO.2&#xff0c;也称为AIO&#xff08;异步IO&#xff09;&#xff0c;在处理大量并发请求时具有优势&#xff0c;特别是在网络编程和高并发场景下&#xff0c;表现得更为出色。 对于输出流和输入流而言&#xff0c;操作的…

sipp模拟uas发送update

概述 freeswitch是一款简单好用的VOIP开源软交换平台。 但是fs在处理update消息时候有BUG&#xff0c;为了复现问题&#xff0c;使用sipp模拟uas&#xff0c;发送update并发送DTMF码。 本文档记录sipp的配置方案。 环境 CentOS 7.9 freeswitch 1.10.7 sipp.3.6.2 问题描…

【Hexo系列】【6】NexT主题使用

本期将为大家讲解Hexo NexT主题的使用。 1. NexT介绍 NexT是Hexo的知名第三方主题&#xff0c;黑白极简风格四合一&#xff0c;有相当多的使用者&#xff0c;维护也相当给力&#xff0c;数年来一直都在频繁更新。 Next主题官网&#xff1a;https://github.com/next-theme/he…