洛谷 P2023 [AHOI2009]维护序列 题解

P2023 [AHOI2009]维护序列

题目描述

老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式:
(1)把数列中的一段数全部乘一个值;
(2)把数列中的一段数全部加一个值;
(3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。

输入格式

第一行两个整数N和P(1≤P≤1000000000)。
第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。
第三行有一个整数M,表示操作总数。
从第四行开始每行描述一个操作,输入的操作有以下三种形式:
操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c(1≤t≤g≤N,0≤c≤1000000000)。
操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。
操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。
同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

输出格式

对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。

输入输出样例

输入 #1

7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7

输出 #1

2
35
8

说明/提示

【样例说明】

初始时数列为(1,2,3,4,5,6,7)。

经过第1次操作后,数列为(1,10,15,20,25,6,7)。

对第2次操作,和为10+15+20=45,模43的结果是2。

经过第3次操作后,数列为(1,10,24,29,34,15,16}

对第4次操作,和为1+10+24=35,模43的结果是35。

对第5次操作,和为29+34+15+16=94,模43的结果是8。

测试数据规模如下表所示

数据编号 1 2 3 4 5 6 7 8 9 10

N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

Source: Ahoi 2009

【思路】

线段树
线段树2改一下输入顺序就可以A掉,,,,,
模板的话去看线段树2就好了
我只在这里说几个易错或者难懂的地方

【取模】

在每一次有加法或者有乘法
涉及到运算的地方能模的都模一下就好了

【乘法和加法】

原来线段树1模板里面有一个lazy
那是因为有加法这种运算
现在有加法和乘法这两种运算
那就开两个类似lazy的东西储存就好了

【lazy标记的修改】

在修改加法lazy标记的时候就正常修改就好了
但是修改乘法的时候就不行了
因为前面可能有加过的数
所以还要连带着一起修改一下加法的lazy标记
因为入过前面加过某个数
那现在就是
(a + b)
这个时候如果乘上一个数c
(a +b) * c = ac + bc
a乘了c,加法的lazy标记也乘了c所以要修改加法的标记

【完整代码】

#include<iostream>
#include<cstdio>
#define int long long
#define lson (k << 1)
#define rson (k << 1 | 1)
using namespace std;
const int Max = 100005;
int read()
{
	int sum = 0,fg = 1;
	char c = getchar();
	while(c < '0' || c > '9')
	{
		if(c == '-')fg = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
	{
		sum = sum * 10 + c - '0';
		c = getchar(); 
	}
	return sum * fg;
}
struct node
{
	int l,r;
	int sum;
	int cheng,jia;
}a[Max << 2];
int n,m,p;
int ans;
int opl,opr,opx;
void build(int k,int l,int r)
{
	a[k].l = l,a[k].r = r;
	a[k].cheng = 1;
	if(l == r)
	{
		a[k].sum = read();
		a[k].sum %= p;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson,l,mid);
	build(rson,mid + 1,r);
	a[k].sum = a[lson].sum + a[rson].sum;
	a[k].sum %= p;
	return;
}

void down(int k)
{
	if(a[k].cheng != 1 || a[k].jia != 0)
	{
		a[lson].sum = (a[lson].sum * a[k].cheng % p + a[k].jia * (a[lson].r - a[lson].l + 1) % p);
		a[lson].sum %= p;
		a[rson].sum = (a[rson].sum * a[k].cheng % p + a[k].jia * (a[rson].r - a[rson].l + 1) % p);
		a[rson].sum %= p;
		a[lson].cheng *= a[k].cheng;
		a[lson].cheng %= p;
		a[rson].cheng *= a[k].cheng;
		a[rson].cheng %= p;
		a[lson].jia = (a[lson].jia * a[k].cheng + a[k].jia) % p;
		a[rson].jia = (a[rson].jia * a[k].cheng + a[k].jia) % p;
		a[k].cheng = 1;
		a[k].jia = 0;
	}
	return;
}

void change1(int k)
{
	if(opl <= a[k].l && opr >= a[k].r)
	{
		a[k].cheng *= opx;
		a[k].cheng %= p;
		a[k].jia *= opx;
		a[k].jia %= p;
		a[k].sum = (a[k].sum * opx) % p;
		return;
	}
	down(k);
	int mid = a[k].l + a[k].r >> 1;
	if(opl <= mid)change1(lson);
	if(opr > mid)change1(rson);
	a[k].sum = a[lson].sum + a[rson].sum;
	a[k].sum %= p;
	return;
}

void change2(int k)
{
	if(opl <= a[k].l && opr >= a[k].r)
	{
		a[k].jia += opx;
		a[k].jia %= p;
		a[k].sum += (a[k].r - a[k].l + 1) * opx;
		a[k].sum %= p;
		return;
	}
	down(k);
	int mid = (a[k].l + a[k].r) >> 1;
	if(opl <= mid)change2(lson);
	if(opr > mid)change2(rson);
	a[k].sum = a[lson].sum + a[rson].sum;
	a[k].sum %= p;
	return;
}

void query(int k)
{
	if(opl <= a[k].l && opr >= a[k].r)
	{
		ans += a[k].sum;
		ans %= p;
		return;
	}
	down(k);
	int mid = (a[k].l + a[k].r) >> 1;
	if(opl <= mid)query(lson);
	if(opr > mid)query(rson);
	return;
}

signed main()
{
	n = read(),p = read();
	build(1,1,n);
	m = read();
	for(register int i = 1;i <= m;++ i)
	{
		int qwq = read();
		if(qwq == 1)
		{
			opl = read(),opr = read(),opx = read();
			change1(1);
		}
		else
		if(qwq == 2)
		{
			opl = read(),opr = read(),opx = read();
			change2(1);
		}
		else
		{
			opl = read(),opr = read();
			ans = 0;
			query(1);
			cout << ans % p << endl;
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/acioi/p/11843305.html