2018牛客暑假多校第十场

本文介绍了一种计算多次前缀和的算法,并通过矩阵快速幂或组合数公式实现。文章详细解释了如何使用差分记录进行修改,并提供了一个能够处理少于500次查询的有效解决方案。

文章目录


#D-Rikka with Prefix Sum
题目链接: https://www.nowcoder.com/acm/contest/148/D

这道题是以前做过的求 K K K 次前缀和再带上修改的题,做这个之前最好先看看这两道:
K K K 次前缀和:https://www.nowcoder.com/acm/contest/109/C
K K K次逆前缀和:https://www.nowcoder.com/acm/contest/117/B

方法就是修改后的矩阵快速幂 或者 组合数公式 来做
0次前缀和: a 1 , a 2 , a 3 , a 4 , a 5 a1, a2, a3, a4, a5 a1,a2,a3,a4,a5
1次前缀和: a 1 , a 1 + a 2 , a 1 + a 2 + a 3 , a 1 + a 2 + a 3 + a 4 , a 1 + a 2 + a 3 + a 4 + a 5 a1,a1+ a2, a1 + a2 + a3, a1 + a2 + a3 + a4, a1 + a2 + a3 + a4 + a5 a1a1+a2a1+a2+a3a1+a2+a3+a4a1+a2+a3+a4+a5
2次前缀和: a 1 , 2 ∗ a 1 + a 2 , 3 ∗ a 1 + 2 ∗ a 2 + a 3 , 4 ∗ a 1 + 3 ∗ a 2 + 2 ∗ a 3 + a 4 , 5 ∗ a 1 + 4 ∗ a 2 + 3 ∗ a 3 + 2 ∗ a 4 + a 5 a1,2*a1 + a2, 3*a1 + 2*a2 + a3, 4*a1 + 3*a2 + 2*a3 + a4, 5*a1 + 4*a2+ 3*a3 + 2*a4 + a5 a12a1+a23a1+2a2+a34a1+3a2+2a3+a45a1+4a2+3a3+2a4+a5
3次前缀和: a 1 , 3 ∗ a 1 + a 2 , 6 ∗ a 1 + 3 ∗ a 2 + a 3 , 10 ∗ a 1 + 6 ∗ a 2 + 3 ∗ a 3 + a 4 , 15 ∗ a 1 + 10 ∗ a 2 + 6 ∗ a 3 + 3 ∗ a 4 + a 5 a1, 3*a1 + a2, 6*a1 + 3*a2 + a3, 10*a1 + 6*a2 + 3*a3 + a4, 15*a1 +10*a2 + 6*a3 + 3*a4 + a5 a13a1+a26a1+3a2+a310a1+6a2+3a3+a415a1+10a2+6a3+3a4+a5
4次前缀和: a 1 , 4 ∗ a 1 + a 2 , 10 ∗ a 1 + 4 ∗ a 2 + a 3 , 20 ∗ a 1 + 10 ∗ a 2 + 4 ∗ a 3 + a 4 , 35 ∗ a 1 + 20 ∗ a 2 + 10 ∗ a 3 + 4 ∗ a 4 + a 5 a1, 4*a1 + a2, 10*a1 + 4*a2 + a3, 20*a1 + 10*a2 + 4*a3 + a4, 35*a1+ 20*a2 + 10*a3 + 4*a4 + a5 a14a1+a210a1+4a2+a320a1+10a2+4a3+a435a1+20a2+10a3+4a4+a5
K K K 次前缀和的组合数公式就是:
C K − 1 + y − x K − 1 C_{K-1+y-x}^{K-1} CK1+yxK1
表示的就是 x x x 这个位置上的值,加了这么多次到 y y y 这个位置上

我们用差分记录下每次的修改,并且记录下这是第几次修改的,于是就可以求得那次修改的值到现在经过了多少次前缀和

而询问区间和的时候就只有一个一个暴力计算,所以他才要求询问次数会小于 500 500 500

#include"bits/stdc++.h"
#define out(x) cout<<#x<<"="<<x
#define C(n,m) (m>n?0:(long long)fac[(n)]*invf[(m)]%MOD*invf[(n)-(m)]%MOD)
using namespace std;
typedef long long LL;
const int maxn=1e6+5;
const int MOD=998244353;
LL ksm(LL a,LL b,LL mod)
{
	LL res=1,base=a;
	while(b)
	{
		if(b&1)res=(res*base)%mod;
		base=(base*base)%mod;
		b>>=1;
	}
	return res;
}
LL fac[maxn]={1,1},invf[maxn]={1,1};
void InitFac(int n)
{
	for(int i=2;i<=n;i++)fac[i]=fac[i-1]*i%MOD;
	invf[n]=ksm(fac[n],MOD-2,MOD);
	for(int i=n-1;i>=2;i--)invf[i]= invf[i+1]*(i+1)%MOD;
}
int N,M,K,cnt;
struct AAA
{
	LL x,k,v;
	AAA(){}
	AAA(LL x,LL k,LL v):x(x),k(k),v(v){}
};
AAA a[maxn];
LL query(int pos)//计算[1,pos]的前缀和 
{
	LL res=0;
	for(int i=1;i<=cnt;i++)
	{
		LL x=a[i].x;
		LL k=a[i].k;
		LL v=a[i].v;
		if(x<=pos)
		{
			int len=pos-x;
			res+=C(K-k+len,K-k)*v;	//②K是当前弄的前缀和的次数,k是那个差分的时候的前缀和次数,所以K-k就是这个值从那个时候到现在的前缀和次数 
			res%=MOD;
		}
	}
	return res;
}
int main()
{
	InitFac(maxn-5);
	int T;
	cin>>T;
	while(T--)
	{
		K=0;//存总共弄了几次前缀和 
		cin>>N>>M;
		cnt=0;
		for(int i=1;i<=M;i++)
		{
			int cmd,L,R,v;
			scanf("%d",&cmd);
			if(cmd==1)
			{
				scanf("%d%d%d",&L,&R,&v);
				a[++cnt]=AAA(L,K-1,v);		//①因为是差分来保存的,所以要减一个前缀和 
				a[++cnt]=AAA(R+1,K-1,-v);
			}
			else if(cmd==2)K++;
			else
			{
				scanf("%d%d",&L,&R);
				cout<<((query(R)-query(L-1))%MOD+MOD)%MOD<<endl;
			}
		}
	}
}
该数据集通过合成方式模拟了种发动机在运行过程中的传感器监测数据,旨在构建一个用于机械系统故障检测的基准资源,特别适用于汽车领域的诊断分析。数据按固定时间间隔采集,涵盖了发动机性能指标、异常状态以及工作模式等维度信息。 时间戳:数据类型为日期时间,记录了每个数据点的采集时刻。序列起始于2024年12月24日10:00,并以5分钟为间隔持续生成,体现了对发动机运行状态的连续监测。 温度(摄氏度):以浮点数形式记录发动机的温度读数。其数值范围通常处于60至120摄氏度之间,反映了发动机在常规工况下的典型温度区间。 转速(转/分钟):以浮点数表示发动机曲轴的旋转速度。该参数在1000至4000转/分钟的范围内随机生成,符合数发动机在正常运转时的转速特征。 燃油效率(公里/升):浮点型变量,用于衡量发动机的燃料利用效能,即每升燃料所能支持的行驶里程。其取值范围设定在15至30公里/升之间。 振动_X、振动_Y、振动_Z:这三个浮点数列分别记录了发动机在三维空间坐标系中各轴向的振动强度。测量值标准化至0到1的标度,较高的数值通常暗示存在异常振动,可能与潜在的机械故障相关。 扭矩(·米):以浮点数表征发动机输出的旋转力矩,数值区间为50至200·米,体现了发动机的负载能力。 功率输出(千瓦):浮点型变量,描述发动机单位时间内做功的速率,取值范围为20至100千瓦。 故障状态:整型分类变量,用于标识发动机的异常程度,共分为四个等级:0代表正常状态,1表示轻微故障,2对应中等故障,3指示严重故障。该列作为分类任务的目标变量,支持基于传感器数据预测故障等级。 运行模式:字符串类型变量,描述发动机当前的工作状态,主要包括:怠速(发动机运转但无负载)、巡航(发动机在常规负载下平稳运行)、重载(发动机承受高负荷或高压工况)。 数据集整体包含1000条记录,每条记录对应特定时刻的发动机性能快照。其中故障状态涵盖从正常到严重故障的四级分类,有助于训练模型实现故障预测与诊断。所有数据均为合成生成,旨在模拟真实的发动机性能变化与典型故障景,所包含的温度、转速、燃油效率、振动、扭矩及功率输出等关键传感指标,均为影响发动机故障判定的重要因素。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值