【CF577B Modulo Sum】题解

题目链接

题目

You are given a sequence of numbers a1, a2, ..., an, and a number m.

Check if it is possible to choose a non-empty subsequence aij such that the sum of numbers in this subsequence is divisible by m.

给出 1 个长度为 n 的序列,以及 1 个正整数 m。问这个原序列中是否存在非空子序列,使其元素之和能被 m 整除。

思路

该不会有人不知道 O(nm) 的做法吧

先说 O(nm) 做法,相当于是一个01背包,每个数选和不选,然而这样会超时。

于是我们考虑 n>m 的情况。

此时我们对整个数列做前缀和,然后再对 m 取模。

根据抽屉原理,因为 n>m,所以在 n 个前缀和中必有两个对 m 取模于是相等,它们中间那段就是答案。

nm 的情况,n103,不会超时。

Code

// Problem: CF577B Modulo Sum
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF577B
// Memory Limit: 250 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 100010
int n, m, i, j, k; 
int dp[N], f[N], x; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); m=read(); 
	if(n>m) return printf("YES"), 0; 
	for(i=1; i<=n; ++i)
	{
		x=read();
		for(j=0; j<m; ++j) f[j]=dp[j];
		for(j=0; j<m; ++j)
			dp[(j+x)%m]+=f[j]; 
		dp[x%m]++; 
	}
	printf("%s", (dp[0] ? "YES" : "NO")); 
	return 0; 
}

posted @   zhangtingxi  阅读(341)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示