牛客竞赛数据结构专题班树状数组、线段树练习题

news2024/11/24 5:05:11

牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ

G 智乃酱的平方数列(线段树,等差数列,多项式)

题目描述
想必你一定会用线段树维护等差数列吧?让我们来看看它的升级版。

请你维护一个长度为5×10 ^5的数组,一开始数组中每个元素都为0,要求支持以下两个操作:

1、区间[l,r]加自然数的平方数组,即al+=1,al+1+=4,al+2+=9,al+3+=16...ar+=(r−l+1)∗(r−l+1)
2、区间[l,r]查询区间和mod 10^9 + 7

输入描述:
第一行输入n,m,(1≤n,m≤5*10 ^5)
接下来m行,对于每行,先读入一个整数q。
当q的值为1时,还需读入两个整l,r,(1≤l≤r≤n)表示需要对区间[l,r]进行操作,让第一个元素加1,第二个元素加4,第三个元素加9...以此类推。
当q的值为2时,还需读入两个整数l,r(1≤l≤r≤n)表示查询l到r的元素和

输出描述:
对于每一个q=2,输出一行一个非负整数,表示l到r的区间和mod 110^9+7。
示例1

输入
复制

4 4
2 1 4
1 1 4
1 3 4
2 1 4
输出
复制

0
35
示例2

输入
复制

10 6
1 1 6
1 8 9
1 3 6
2 1 10
1 1 10
2 1 10
输出
复制

126
511


解析: 

等差数列可以写成 [x-(l-1)]^2,其中 x 表示当前的位置,等价于 x^2-2*x*(l-1)+(l-1)^2,通过线段树维护其系数即可

#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <math.h>
#include <map>
#include <sstream>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <stdio.h>
#include <tuple>
using namespace std;
/*
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
*/
typedef long long LL;
#define int long long
#define ld long double
//#define INT __int128
const LL INF = 0x3f3f3f3f3f3f3f3f;
typedef unsigned long long ULL;
typedef pair<long long, long long> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9+7;
const ld eps = 1e-12;
const int N = 5e5 + 10, M = N + 10;
int n, m;
struct TREE {
	int l, r;
	int la1, la2, la3;
	int sum;
	int base1, base2;
}tr[N << 2];
#define ls u<<1
#define rs u<<1|1
void cal(int u, int la1, int la2, int la3) {
	la3 %= mod;
	int len = tr[u].r - tr[u].l + 1;
	tr[u].sum = (tr[u].sum + len * la3 % mod) % mod;
	tr[u].sum = (tr[u].sum - 2 * tr[u].base2 * la2 % mod + mod) % mod;
	tr[u].sum = (tr[u].sum + tr[u].base1 * la1 % mod) % mod;
	tr[u].la1 = (tr[u].la1 + la1) % mod;
	tr[u].la2 = (tr[u].la2 + la2) % mod;
	tr[u].la3 = (tr[u].la3 + la3) % mod;
}
void up(int u) {
	tr[u].sum = (tr[ls].sum + tr[rs].sum) % mod;
}
void down(int u) {
	if (tr[u].la1||tr[u].la2||tr[u].la3) {
		cal(ls, tr[u].la1, tr[u].la2, tr[u].la3);
		cal(rs, tr[u].la1, tr[u].la2, tr[u].la3);
		tr[u].la1 = tr[u].la2 = tr[u].la3 = 0;
	}
}
void build(int u, int l, int r) {
	tr[u].l = l, tr[u].r = r;
	if (l == r) {
		tr[u].base1 = (l * l) % mod , tr[u].base2 = l;
		return;
	}
	int mid = (l + r) >> 1;
	build(ls, l, mid), build(rs, mid + 1, r);
	tr[u].base1 = (tr[ls].base1 + tr[rs].base1) % mod;
	tr[u].base2 = (tr[ls].base2 + tr[rs].base2) % mod;
}
void modify(int u, int l, int r, int d) {
	if (l <= tr[u].l && tr[u].r <= r) {
		cal(u, 1, d, d * d);
		return;
	}
	down(u);
	int mid = (tr[u].l + tr[u].r) >> 1;
	if (l <= mid)modify(ls, l, r, d);
	if (r > mid)modify(rs, l, r, d);
	up(u);
}
int query(int u, int l, int r) {
	if (l <= tr[u].l && tr[u].r <= r) {
		return tr[u].sum;
	}
	down(u);
	int ret = 0;
	int mid = (tr[u].l + tr[u].r) >> 1;
	if (l <= mid)ret = (ret + query(ls, l, r)) % mod;
	if (r > mid)ret = (ret + query(rs, l, r)) % mod;
	//up(u);
	return ret;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin >> n >> m;
	build(1, 1, n);
	int op, l, r;
	while (m--) {
		cin >> op >> l >> r;
		if (op == 1) {
			modify(1, l, r, l - 1);
		}
		else {
			cout << query(1, l, r) << endl;
		}
	}
	return 0;
}
/*
4 5
2 1 4
1 1 4
2 1 4
1 3 4
2 1 4
4 5
2 1 4
1 3 4
2 1 4
1 1 4
2 1 4
*/

K    智乃酱的双塔问题·改(线段树,dp,矩阵连乘)

解析:

不能发现这个问题如果不带修改则可以用 dp+前缀和(矩阵乘法)解决,带修改则可以用线段树维护区间和。

令 f[i][0/1] 表示从第 1 层的左边(0)或右边(1)到第 i 层的左边(0)或右边(1)的方案数

我们可以将每一层的转移状态用矩阵表示,

#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <math.h>
#include <map>
#include <sstream>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <stdio.h>
#include <tuple>
using namespace std;
/*
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
*/
typedef long long LL;
//#define int long long
#define ld long double
//#define INT __int128
const LL INF = 0x3f3f3f3f3f3f3f3f;
typedef unsigned long long ULL;
typedef pair<long long, long long> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const ld eps = 1e-12;
const int N = 2e5 + 10, M = N + 10;
int n, m;
char s[N];
struct MATRIX {
	LL a[2][2];
	void init(int b1,int b2,int b3,int b4) {
		a[0][0] = b1, a[0][1] = b2;
		a[1][0] = b3, a[1][1] = b4;
	}
	MATRIX operator*(MATRIX oth) {
		MATRIX ret;
		ret.init(0, 0, 0, 0);
		for (int i = 0; i < 2; i++) {
			for (int j = 0; j < 2; j++) {
				for (int k = 0; k < 2; k++) {
					(ret.a[i][j] += a[i][k] * oth.a[k][j] % mod) %= mod;
				}
			}
		}
		return ret;
	}
};

struct TREE {
	int l, r;
	MATRIX ma;
}tr[N << 2];
#define ls u<<1
#define rs u<<1|1
void up(int u) {
	tr[u].ma = tr[ls].ma * tr[rs].ma;
}
void build(int u, int l, int r) {
	tr[u].l = l, tr[u].r = r;
	if (l == r) {
		tr[u].ma.init(1, s[l] == '/', s[l] != '/', 1);
		return;
	}
	int mid = l + r >> 1;
	build(ls, l, mid), build(rs, mid + 1, r);
	up(u);
}
void modify(int u, int pos, char ch) {
	if (tr[u].l == tr[u].r) {
		tr[u].ma.init(1, ch == '/', ch != '/', 1);
		return;
	}
	int mid = tr[u].l + tr[u].r >> 1;
	if (pos <= mid)modify(ls, pos, ch);
	if (pos > mid)modify(rs, pos, ch);
	up(u);
}
MATRIX query(int u, int l, int r) {
	if (l <= tr[u].l && tr[u].r <= r) {
		return tr[u].ma;
	}
	int mid = tr[u].l + tr[u].r >> 1;
	MATRIX ret;
	ret.init(1, 0, 0, 1);
	if (l <= mid)ret = (ret * query(ls, l, r));
	if (r > mid)ret = (ret * query(rs, l, r));
	return ret;
}
signed main() {
	cin >> n >> m;
	scanf("%s", s + 1);
	build(1, 1, n - 1);
	int op, ht, hs, h;
	for (int i = 1; i <= m; i++) {
		scanf("%d", &op);
		if (op == 0) {
			char c[2];
			scanf("%d%s",&h, c);
			modify(1, h,c[0]);
		}
		else {
			int ps, pt;
			scanf("%d%d%d%d",&hs,&ht, &ps, &pt);
			auto ret = query(1, hs, ht - 1);
			/*cout << "__________________" << endl;
			for (int i = 0; i < 2; i++) {
				cout << ret.a[i][0] << " " << ret.a[i][1] << endl;
			}
			cout << endl;*/
			LL ans = ret.a[ps][pt];
			printf("%lld\n", ans);
		}
	}
	return 0;
}

J    智乃酱的双塔问题·极(带修改的DP,DDP)

这题思路与上题一样,只不过将矩阵的乘法运算换成 floyd 算法,矩阵的含义变为图的邻接矩阵。(可以变的主要原因是因为 floyd 算法的运算形式与矩阵连乘的形式很相似)

#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <math.h>
#include <map>
#include <sstream>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <stdio.h>
#include <tuple>
using namespace std;
/*
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
*/
typedef long long LL;
//#define int long long
#define ld long double
//#define INT __int128
const LL INF = 0x3f3f3f3f3f3f3f3f;
typedef unsigned long long ULL;
typedef pair<long long, long long> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const ld eps = 1e-12;
const int N = 1e5 + 10, M = N + 10;
int n, m;
int val[N][3];
char s[N];
#define inf INF
struct MATRIX {
	LL a[2][2];
	void init(LL b1, LL b2, LL b3, LL b4) {
		a[0][0] = b1, a[0][1] = b2;
		a[1][0] = b3, a[1][1] = b4;
	}
	MATRIX operator*(MATRIX oth) {
		MATRIX ret;
		ret.init(inf, inf, inf, inf);
		for (int i = 0; i < 2; i++) {
			for (int j = 0; j < 2; j++) {
				for (int k = 0; k < 2; k++) {
					//(ret.a[i][j] += a[i][k] * oth.a[k][j] % mod) %= mod;
					if (a[i][k] == inf || oth.a[k][j] == inf)continue;
					ret.a[i][j] = min(ret.a[i][j], (a[i][k] + oth.a[k][j]));
				}
			}
		}
		return ret;
	}
};

struct TREE {
	int l, r;
	MATRIX ma;
}tr[N << 2];
#define ls u<<1
#define rs u<<1|1
void up(int u) {
	tr[u].ma = tr[ls].ma * tr[rs].ma;
}
void build(int u, int l, int r) {
	tr[u].l = l, tr[u].r = r;
	if (l == r) {
		if (s[l] == '/')
			tr[u].ma.init(val[l][0], val[l][2], inf, val[l][1]);
		else tr[u].ma.init(val[l][0], inf, val[l][2], val[l][1]);
		return;
	}
	int mid = l + r >> 1;
	build(ls, l, mid), build(rs, mid + 1, r);
	up(u);
}
void modify(int u, int pos, char ch, int val1, int val2, int val3) {
	if (tr[u].l == tr[u].r) {
		if (ch == '/')
			tr[u].ma.init(val1, val3, inf, val2);
		else tr[u].ma.init(val1, inf, val3, val2);
		return;
	}
	int mid = tr[u].l + tr[u].r >> 1;
	if (pos <= mid)modify(ls, pos, ch, val1, val2, val3);
	if (pos > mid)modify(rs, pos, ch, val1, val2, val3);
	up(u);
}
MATRIX query(int u, int l, int r) {
	if (l <= tr[u].l && tr[u].r <= r) {
		return tr[u].ma;
	}
	int mid = tr[u].l + tr[u].r >> 1;
	MATRIX ret;
	ret.init(0, inf, inf, 0);
	if (l <= mid)ret = ret * query(ls, l, r);
	if (r > mid)ret = ret * query(rs, l, r);
	return ret;
}
signed main() {
	cin >> n >> m;
	scanf("%s", s + 1);
	for (int i = 1; i < n; i++) {
		scanf("%d%d%d", &val[i][0], &val[i][1], &val[i][2]);
	}
	build(1, 1, n - 1);
	int op, ht, hs, h;
	for (int i = 1; i <= m; i++) {
		scanf("%d", &op);
		if (op == 0) {
			char c[2];
			scanf("%d%s", &h, c);
			//cout << "______" << c[0] << endl;
			s[h] = c[0];
			modify(1, h, c[0], val[h][0], val[h][1], val[h][2]);
		}
		else if (op == 1) {
			int val1, val2, val3;
			scanf("%d%d%d%d", &h, &val1, &val2, &val3);
			val[h][0] = val1, val[h][1] = val2, val[h][2] = val3;
			modify(1, h, s[h], val1, val2, val3);
		}
		else {
			int ps, pt;
			scanf("%d%d%d%d", &hs, &ht, &ps, &pt);
			auto ret = query(1, hs, ht - 1);
			/*cout << "__________________" << endl;
			for (int i = 0; i < 2; i++) {
				cout << ret.a[i][0] << " " << ret.a[i][1] << endl;
			}
			cout << endl;*/
			LL ans = ret.a[ps][pt];
			if (ans == inf) {
				printf("-1\n");
			}
			else
				printf("%lld\n", ans);
		}
	}
	return 0;
}

/*
4 13
///
1 2 1
2 3 5
8 8 1
2 1 4 1 0
2 1 2 1 0
2 2 3 1 0
2 3 4 1 0
0 3 \
2 1 4 0 0
2 2 4 0 0
2 2 4 0 1
2 3 4 0 1
2 3 4 1 0
1 1 1 1 1
1 2 1 1 1
1 3 1 1 1
2 1 4 1 0
0 3 /
2 1 4 1 0


4 13
///
1 2 1
2 3 5
8 8 1
2 1 4 1 0
0 3 \
2 1 4 0 0
2 2 4 0 0
2 2 4 0 1
2 3 4 0 1
2 3 4 1 0
1 1 1 1 1
1 2 1 1 1
1 3 1 1 1
2 1 4 1 0
0 3 /
2 1 4 1 0
*/

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

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

相关文章

Mysql高级 [Linux版] 性能优化 数据库系统配置优化 和 MySQL的执行顺序 以及 Mysql执行引擎介绍

数据库系统配置优化 1、定义 数据库是基于操作系统的&#xff0c;目前大多数MySQL都是安装在linux系统之上&#xff0c;所以对于操作系统的一些参数配置也会影响到MySQL的性能&#xff0c;下面就列出一些常用的系统配置。 2、优化配置参数-操作系统 优化包括操作系统的优化及My…

集运系统:如何实现不同员工的不同操作权限?

在集运行业&#xff0c;员工的角色和职责各有不同&#xff0c;因此对系统的操作权限需求也不尽相同。为了确保数据的安全性和业务的顺利进行&#xff0c;易境通集运系统提供了灵活的权限管理功能&#xff0c;让企业可以根据员工的角色和职责&#xff0c;设置不同的操作权限。 易…

Redis (day 3)

一、通过jedis连接数据库 1.首先导入依赖 <!-- https://mvnrepository.com/artifact/redis.clients/jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.1.0</version></de…

mac 微信数据直接存储到移动硬盘

在apple设备上存储都是1500块/128gb的价格收取的&#xff0c;真的是寸土寸金。在手机已经占用了一遍存储空间之后&#xff0c;微信备份还要占用一遍。 iCloud备份微信聊天记录的稳定性真的非常差劲&#xff0c;比如我微信30g&#xff0c;经常恢复到20g左右就被打断&#xff0c;…

【C++ Primer Plus习题】2.6

问题: 解答: #include <iostream> using namespace std;#define LIGHT_TO_SKY 63240double lightToSky(double value) {return value * LIGHT_TO_SKY; }int main() {double light 0;cout << "请输入光年值:";cin >> light;cout << light &…

还在返回一大堆 null 字段给前端?

在许多情况下&#xff0c;返回的 JSON 数据可能包含许多 null 值的字段&#xff0c;这会导致数据冗余&#xff0c;增加网络传输的负担&#xff0c;并使得前端处理数据变得复杂。因此&#xff0c;使用 JsonInclude(JsonInclude.Include.NON_NULL) 可以帮助我们优化 JSON 的输出&…

看看人家写的,Controller太优雅了~【送源码】

今天咱们来聊聊如何写出优雅的Controller代码。 写程序想让作品成为经典&#xff0c;不只是简单地加个try-catch就完事了。有时候&#xff0c;一个不小心&#xff0c;Controller里写的业务逻辑都能让你血压飙升&#xff01;不过别慌&#xff0c;今天我就来带大家看看怎么把Cont…

文件描述符的复制,访问测试,修改文件大小,文件锁

指定文件描述符 #include <unistd.h>int dup2(int oldfd, int newfd); ->功能:复制文件描述符表的特定条目到指定项&#xff0c; ->参数:oldfd: 源文件描述符 newfd: 目标文件描述符 ->返回值:成功返回目标文件描述符(newfd)&#xff0c;失败返回…

【C++ 面试 - 面向对象】每日 3 题(八)

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

P(查准率) R(查全率) AP mAP最通俗准确的讲解

学习YOLO的过程中遇到了mAP指标&#xff0c;在网上看了很多关于mAP的讲解&#xff0c;不是很理解其计算过程&#xff0c;于是总结了各个帖子及自己的理解&#xff0c;给出mAP计算的规律&#xff0c;这样就能很好的记忆。 目录 一、P&#xff08;精确率&#xff09;、R&#x…

I2C通信协议(软件I2C和硬件I2C)

相比于之前学的异步全双工且需要两条通信线的串口通信&#xff0c;I2C则为同步半双工&#xff0c;仅需要一条通信线&#xff0c;全双工与半双工区别如下&#xff1a; 全双工&#xff08;Full Duplex&#xff09;半双工&#xff08;Half Duplex&#xff09;数据传输方式同时双向…

linux 磁盘满了,程序运行失败,如何处理?df -h

场景&#xff1a;紧急呼救&#xff0c;上传图片失败了。我一脸懵&#xff0c;服务器这是又咋地了&#xff0c;别邪乎姐姐&#xff0c;姐姐胆子小啊。 一、寻找问题原因 1、OSS出问题了&#xff1f; 然后我尝试了 IOS 的APP是没问题的&#xff0c;Android提示上传失败&#xf…

Excel技巧(一)

快捷键技巧 原文链接 选取某一行的数据直到最后一行&#xff1a;【CTRL SHIFT ↓ 】或者选取一行后按住SHIFT键&#xff0c;双击下边线就可以快速选取区域。 如果表格中有多行空行&#xff0c;可以先按CTRL SHIFT END&#xff0c;再按CTRL SHIFT 上下键调整&#xff0c;…

CodeLLDB的快速安装

1、CodeLLDB很难安装 ‌‌CodeLLDB插件是一个基于‌LLDB的调试器插件&#xff0c;专为‌Visual Studio Code设计&#xff0c;旨在提供类似于传统集成开发环境&#xff08;IDE&#xff09;的调试体验。‌ 它支持‌C、‌C和‌Objective-C程序的调试&#xff0c;包括设置断点、查…

这4款工具可以教会你如何用AI写ppt.

随着AI工具的盛行&#xff0c;AI办公工具也组建越来越多&#xff0c;我们可以用AI帮助生成各种文档&#xff0c;包括PPT。今天我就帮大家总结一波专业又好用的ai生成PPT的工具&#xff0c;一共有4款。 1、笔灵ppt 直通车&#xff1a;https://ibiling.cn/ppt-zone 首先要说的这…

颠茄和草本曼陀罗参考基因组(茄科)

茄科的代表性物种之二&#xff1a;颠茄和草本曼陀罗 来源文献 Revealing evolution of tropane alkaloid biosynthesis by analyzing two genomes in the Solanaceae family 推荐 惕佫酰假托品合酶的发现-文献精读28 参考链接 https://ngdc.cncb.ac.cn/gwh/Assembly/29467/s…

【Python零基础】Python中的函数

文章目录 前言一、函数定义二、传递实参三、返回值四、传递列表五、传递任意数量实参六、把函数存储在模块中七、函数定义指南总结 前言 在Python中&#xff0c;函数是一段可重用的代码块&#xff0c;用于执行特定任务。函数可以通过定义关键字 def 来创建&#xff0c;并且通常…

网络安全-防火墙安全策略初认识

文章目录 前言理论介绍1. 安全策略1.1 定义&#xff1a;1.2 关键术语&#xff1a; 2. 防火墙状态监测 实战步骤1&#xff1a;实验环境搭建步骤2&#xff1a;配置实现 总结1. 默认安全策略2. 自定义安全策略3. 防火墙状态会话表 前言 who&#xff1a;本文主要写给入门防火墙的技…

容器篇(Java - 集合)

目录 有意者可加 一、集合 1. 出现的背景 2. 带大家具体了解下集合 3. 集合带来了哪些好处 4. 集合的特点 5. 集合和数组对比 6. 数组和集合应用场景&#xff08;对比&#xff09; 6.1 数组的应用场景 1. 存储一组数据 2. 图像处理 3. 矩阵运算 4. 缓存 6.2 集合…