首页 > 其他分享 >P1438 无聊的数列

P1438 无聊的数列

时间:2024-12-22 21:19:57浏览次数:4  
标签:pr 数列 无聊 ll mid tag base pl P1438

链接:https://www.luogu.com.cn/problem/P1438
题面:

思路:
差分+线段树。
刚开始的想法是建立一个双tag线段树:basetag和addtag。然后传递的时候basetag就是l的基准,addtag不变。求的话就是求节点值。
但是这样容易溢出。。。
所以考虑差分:利用前缀和代替当前某一点的值:query(1,n) = val[n]
所以:注意点

  • 初始数据的输入
    采用后到前差分的形式,确保前缀和是当前值。
    代码:
    for (ll i = 1; i <= n; i++)cin >> a[i];
    for (ll i = n; i >= 1; i--)a[i] -= a[i - 1];
    
  • tag的使用
    实际上这里的tag就相当于[l+1,r]的区间里面都加上一个delta。然后[l]处加上一个base。[r]处加上一个-base-(r-l)*delta
    update(L , L, 1, 1, n, base);
    update(R+1, R+1, 1, 1, n, -base-(R-L)*d);
    update(L+1, R, 1, 1, n, d);
    
  • 最后添加条件判断
    注意到只有R不比n大的时候才可以添加补偿数,以及L小于R的时候才可以添加d。
    update(L , L, 1, 1, n, base);
    if(R<n)update(R+1, R+1, 1, 1, n, -base-(R-L)*d);
    if(L<R)update(L+1, R, 1, 1, n, d);
    

总的代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll a[N];
ll tree[N << 2];
ll tag[N << 2];


ll ls(ll p)
{
	return p << 1;
}
ll rs(ll p)
{
	return p << 1 | 1;
}
void push_up(ll p)
{
	tree[p] = tree[ls(p)] + tree[rs(p)];
	//从下往上传递 
}
void build(ll p, ll pl, ll pr)
{
	tag[p] = 0;
	if (pl == pr) { tree[p] = a[pl]; return; }
	ll mid = (pl + pr) >> 1;
	build(ls(p), pl, mid);
	build(rs(p), mid + 1, pr);
	push_up(p);
}
void addtag(ll p, ll pl, ll pr, ll d)
{
	//改,加上tag的作用 
	
	tag[p] += d;
	tree[p] += d * (pr - pl + 1);
}

void push_down(ll p, ll pl, ll pr)
{
	if (tag[p])
	{
		ll mid = (pl + pr) >> 1;
		addtag(ls(p), pl, mid,tag[p]);
		addtag(rs(p), mid + 1, pr,tag[p]);
		tag[p] = 0;
	}
}
void update(ll L, ll R, ll p, ll pl, ll pr, ll d)
{
	if (L <= pl and pr <= R)
	{
		addtag(p, pl, pr, d);
		return;
	}
	push_down(p, pl, pr);
	ll mid = (pl + pr) >> 1;
	if (L <= mid)update(L, R, ls(p), pl, mid, d);
	if (R > mid)update(L, R, rs(p), mid + 1, pr, d);
	push_up(p);
}


ll query(ll L, ll R, ll p, ll pl, ll pr)
{
	if (pl >= L and R >= pr)return tree[p];
	push_down(p, pl, pr);
	ll res = 0;
	ll mid = (pl + pr) / 2;
	if (L <= mid)res += query(L, R, ls(p), pl, mid);
	if (R > mid)res += query(L, R, rs(p), mid + 1, pr);
	return res;
}

signed main()
{
	IOS;
	ll n, m;
	cin >> n >> m;
	for (ll i = 1; i <= n; i++)cin >> a[i];
	for (ll i = n; i >= 1; i--)a[i] -= a[i - 1];
	build(1, 1, n);

	while (m--)
	{
		ll q, L, R, d;
		cin >> q;
		if (q == 1)
		{
			ll base;
			cin >> L >> R >>base>> d;
			update(L , L, 1, 1, n, base);
			if(R<n)update(R+1, R+1, 1, 1, n, -base-(R-L)*d);
			if(L<R)update(L+1, R, 1, 1, n, d);


		}
		else {
			cin  >> R;
			cout << query(1, R, 1, 1, n)<<'\n';
		}
	}

	return 0;
}

标签:pr,数列,无聊,ll,mid,tag,base,pl,P1438
From: https://www.cnblogs.com/zzzsacmblog/p/18622561

相关文章

  • 动态规划算法-子数组系列之_等差数列划分
    413.等差数列划分( Leetcode)等差数列划分题目描述如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。例如,[1,3,5,7,9]、[7,7,7,7] 和 [3,-1,-5,-9] 都是等差数列。给你一个整数数组 nums ,返回数组 nums 中所有为等差数组的 子......
  • 38. 外观数列
    题目链接解题思路:就是一个递归。弄清楚题目意思,n=1时,就返回1,然后n=2时,返回上一个结果,上一个结果是一个1,所以就是11,然后n=3,返回上一个结果,就是两个1,所以就是21代码classSolution{public:stringcountAndSay(intn){if(n==1){return"1......
  • 动态规划在斐波那契数列中的应用与优化
    文章目录前言......
  • 蓝桥杯数列求值(2019试题C)
    【问题描述】     给定数列1,1,1,3,5,7,17……从第4项开始,每项都是前3项的和。求第20190324项的最后4位数字。【答案提交】    这是一道结果填空题,考生只需要计算出结果并提交即可。本题的结果为一个4位整数(提示:答案的千位不为0),在提交答案时只填写这个......
  • 华为机试HJ100 等差数列
    首先看一下题描述等差数列 2,5,8,11,14。。。。(从2开始的3为公差的等差数列)输出求等差数列前n项和数据范围:1≤n≤1000 输入描述:输入一个正整数n。输出描述:输出一个相加后的整数。示例1输入:2输出:7说明:2+5=7示例2输入:275输出:113575说明:2+5+...+82......
  • 「Mac玩转仓颉内测版47」小学奥数篇10 - 数列求和
    本篇将通过Python和Cangjie双语实现数列求和的计算。通过这个题目,学生将学会如何通过公式法和循环法求解等差数列与等比数列的和。关键词小学奥数Python+Cangjie数列求和一、题目描述编写一个程序,计算等差数列和等比数列的和。用户输入首项、公差/公比以及项数,......
  • 打卡信奥刷题(382)用C++信奥B3693[普及组/提高] 数列前缀和 4
    数列前缀和4题目背景这次不是数列的问题了。题目描述给定一个nnn行mm......
  • 斐波那契数列c++
    意大利数学家斐波那契(LeonardoFibonacci)是12、13世纪欧洲数学界的代表人物。他提出的“兔子问题”引起了后人的极大兴趣。“兔子问题”假定一对大兔子每一个月可以生一对小兔子,而小兔子出生后两个月就有繁殖能力,问从一对小兔子开始,n个月后能繁殖成多少对兔子?输入格式:首先......
  • 【特殊子序列 DP】【hard】力扣446. 等差数列划分 II - 子序列
    给你一个整数数组nums,返回nums中所有等差子序列的数目。如果一个序列中至少有三个元素,并且任意两个相邻元素之差相同,则称该序列为等差序列。例如,[1,3,5,7,9]、[7,7,7,7]和[3,-1,-5,-9]都是等差序列。再例如,[1,1,2,5,7]不是等差序列。数组中的......
  • 接龙数列(第十四届蓝桥杯C++B组JAVA题解 动态规划)
    对于一个长度为 KK 的整数数列:A1,A2,...,AK,我们称之为接龙数列当且仅当 Ai 的首位数字恰好等于 Ai−1 的末位数字(2≤i≤K)。例如 12,23,35,56,61,11是接龙数列;12,23,34,56不是接龙数列,因为 56的首位数字不等于 3434 的末位数字。所有长度为 11 的整数数列都......