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

登录---专业IT笔试面试备考平台_牛客网

链接:登录---专业IT笔试面试备考平台_牛客网

来源:牛客网

题目描述

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

请你维护一个长度为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,通过线段树维护其系数即可

cpp 复制代码
#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

*/
相关推荐
破东风9 分钟前
leetcode每日一题:替换子串得到平衡字符串
算法·leetcode·滑动窗口
Hole_up19 分钟前
蓝桥杯真题-分糖果-题解
python·算法·职场和发展·蓝桥杯
十五年专注C++开发30 分钟前
QT 中的元对象系统(五):QMetaObject::invokeMethod的使用和实现原理
开发语言·数据结构·c++·qt·设计模式
泛舟起晶浪33 分钟前
特殊的质数肋骨--dfs+isp
算法·深度优先
GGBondlctrl34 分钟前
【leetcode】记录与查找:哈希表的题型分析
算法·力扣·两数之和·字母异位词分组·存在重复字符2
视觉AI43 分钟前
研究下适合部署在jeston上的深度学习类单目标跟踪算法
深度学习·算法·目标跟踪
独好紫罗兰1 小时前
洛谷题单3-P1075 [NOIP 2012 普及组] 质因数分解-python-流程图重构
开发语言·python·算法
daily_23332 小时前
coding ability 展开第九幕(位运算——进阶篇)超详细!!!!
算法·位运算
柏木乃一2 小时前
双向链表增删改查的模拟实现
开发语言·数据结构·算法·链表
whltaoin4 小时前
Java实现N皇后问题的双路径探索:递归回溯与迭代回溯算法详解
java·算法