jzoj6312-Lottery【dp,前缀和】

77 篇文章 0 订阅

正题


题目大意

给出一个长度为 n n n的序列 a a a和数字 l l l,定义两个长度为 l l l的区间 [ l 1 , r 1 ] [l_1,r_1] [l1,r1] [ l 2 , r 2 ] [l_2,r_2] [l2,r2]的距离为有多少个不相同的数字。

然后有 q q q个询问 k i k_i ki,要求输出有多少对距离为 k i k_i ki的区间。


解题思路

我们发现若我们求出了 [ l 1 , r 1 ] [l_1,r_1] [l1,r1] [ l 2 , r 2 ] [l_2,r_2] [l2,r2]的距离,就可以 O ( 1 ) O(1) O(1)求出 [ l 1 + 1 , r 1 + 1 ] [l_1+1,r_1+1] [l1+1,r1+1] [ l 2 + 1 , r 2 + 1 ] [l_2+1,r_2+1] [l2+1,r2+1]的距离(两个 i f if if即可)。

我们可以枚举计算的区间对的位置差

所以我们可以用 a n s i , j ans_{i,j} ansi,j表示区间 [ i , i + l − 1 ] [i,i+l-1] [i,i+l1]有多少个与其距离为 j j j的区间。然后做个前缀和即可。

时空间复杂度都是 O ( n 2 ) O(n^2) O(n2)。我们发现空间复杂度并不能胜任,所以我们可以将 a n s i , j ans_{i,j} ansi,j j j j的意义变为有多少个与其距离为 k j k_j kj的区间。

然后空间复杂度 O ( n q ) O(nq) O(nq)


c o d e code code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=11000;
int n,q,a[N],x[N],num[N],ans[N][110],L;
bool v[N];
int main()
{
	freopen("lottery.in","r",stdin);
	//freopen("lottery.out","w",stdout);
	scanf("%d%d",&n,&L);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	scanf("%d",&q);
	for(int i=1;i<=q;i++)
		scanf("%d",&x[i]),v[x[i]+1]=1;
	num[0]=1;
	for(int i=1;i<=n;i++)
		num[i]=num[i-1]+v[i];
	for(int l=1;l<=n;l++){
		int dis=0;
		if(l+L>n) break; 
		for(int i=1;i<=L;i++)
			if(a[i]!=a[i+l]) dis++;
		ans[1][num[dis]]++;
		ans[1+l][num[dis]]++;
		for(int i=2;i<=n-L+1;i++){
			int j=i+l;
			if(j>n-L+1) break;
			if(a[i-1]!=a[j-1]) dis--;
			if(a[i+L-1]!=a[j+L-1]) dis++;
			ans[i][num[dis]]++;
			ans[j][num[dis]]++;
		}
	}
	for(int i=1;i<=num[n];i++)
		for(int j=1;j<=n;j++)
			ans[j][i]+=ans[j][i-1];
	for(int i=1;i<=q;i++){
		for(int j=1;j<=n-L+1;j++)
			printf("%d ",ans[j][num[x[i]]]);
		putchar('\n');
	}
}
抽奖系统是一种常见的应用,在设计抽奖系统时,使用基于领域驱动设计(Domain-Driven Design,DDD)的四层架构可以提供更好的架构实践。 在四层架构中,首先是用户界面层(User Interface Layer),用户界面层负责向用户展示抽奖界面,并接收用户的输入请求。用户界面层可以采用Web页面、移动应用等形式实现。通过使用领域驱动设计,用户界面层可以更加贴近用户需求,提供更好的用户体验。 接下来是应用层(Application Layer),应用层是整个抽奖系统的核心。应用层负责处理用户请求,协调各个领域对象之间的交互,并调用相应的领域服务和聚合根进行业务逻辑的处理。应用层在领域驱动设计中起到了承上启下的作用,通过定义和实现各种用例和操作,实现了系统的功能。 在领域层(Domain Layer)中,定义了抽奖系统中的核心业务逻辑。领域层包含了各种实体、值对象、聚合根等领域对象,通过这些领域对象的交互实现了系统的业务流程。在抽奖系统中,可以定义抽奖活动、参与者、奖品等领域对象,并在领域层中定义它们的行为和属性,从而满足系统的各项业务需求。 最后是基础设施层(Infrastructure Layer),基础设施层提供了抽奖系统运行所需的各种支持服务,包括数据库、缓存、消息队列等。在抽奖系统中,基础设施层可以提供参与者信息的持久化存储、抽奖结果的发送等功能。通过将基础设施逻辑与领域逻辑相分离,可以提高系统的可维护性和可扩展性。 综上所述,基于领域驱动设计的四层架构可以有效地设计和实现抽奖系统。通过将系统的核心业务逻辑与界面、应用和基础设施进行分离,可以实现系统的高内聚、低耦合,提供更好的扩展性和可维护性。同时,领域驱动设计还能够更好地满足用户需求,提供更好的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值