CF557B Modulo Sum/Namomo Spring Camp 每日一题 Week1 Day4 选数

Namomo Spring Camp 2022 Week1 Day4 选数

Problem Statement

N N N个数 a 1 , a 2 , … , a n a_1,a_2,\dots,a_n a1,a2,,an选出若干个数字, 使得数字的和 m o d    N = 0 \mod N=0 modN=0.

输出一个方案.

Solution

首先设 b k = ( ∑ i = 1 k a i ) m o d    N b_k=(\sum_{i=1}^ka_i)\mod N bk=(i=1kai)modN. b k = { 0 , 1 , 2 , … , N − 1 } b_k=\{0,1,2,\dots,N-1\} bk={0,1,2,,N1}.

  • 如果 b k = 0 b_k=0 bk=0那么显然有 b k = ( ∑ i = 1 k a i ) m o d    N = 0 b_k=(\sum_{i=1}^ka_i)\mod N=0 bk=(i=1kai)modN=0即选择 [ 1 , k ] [1,k] [1,k]的所有数即可.
  • 否则 ∀ k ∈ [ 1 , N ] , b k ≠ 0 \forall k\in[1,N],b_k\neq0 k[1,N],bk=0, 由于 b k ≠ 0 b_k\neq0 bk=0的值域为 { 1 , 2 , … , N − 1 } \{1,2,\dots,N-1\} {1,2,,N1} N − 1 N-1 N1个数, 由鸽笼原理 N N N个数 b k b_k bk中至少有 2 2 2个数使得 b l = b r ( l < r ) b_l=b_r(l<r) bl=br(l<r). 那么显然有 b r − b l = ( ∑ i = l + 1 r a i ) m o d    N = 0 b_r-b_l=(\sum_{i=l+1}^ra_i)\mod N=0 brbl=(i=l+1rai)modN=0. 则选择 [ l + 1 , r ] [l+1,r] [l+1,r]区间内的所有数即可.

时间复杂度为 O ( N ) O(N) O(N).

Code

# define Fast_IO std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
# include "unordered_map"
# include "algorithm"
# include "iostream"
# include "cstdlib"
# include "cstring"
# include "cstdio"
# include "vector"
# include "bitset"
# include "queue"
# include "cmath"
# include "map"
# include "set"

using namespace std;

const int maxm=1e5+10;

int N,A[maxm],B[maxm];
unordered_map<int,int> LH;

int main(){
	static int i,L,R; L=0,R=1;
	scanf("%d",&N);
	for(i=1;i<=N;i++) scanf("%d",&A[i]),B[i]=(B[i-1]+A[i]%N)%N;
	for(i=1;i<=N;i++){
		if(LH[B[i]] || B[i]==0){
			L=LH[B[i]],R=i;
			break;
		}else LH[B[i]]=i;
	}
	printf("%d\n",R-L);
	for(i=L+1;i<=R;i++) printf("%d ",i);
	return 0;
}

CF557B Modulo Sum

Problem Statement

给你 N N N个数, 选出若干个数使得, 这若干个数的和 m o d    M = 0 \mod M=0 modM=0. 判断可不可行.

  • 1 ≤ N ≤ 1 0 6 , 2 ≤ M ≤ 1 0 3 1\leq N\leq 10^6,2\leq M\leq10^3 1N106,2M103.

Solution

由上题性质可知若 N ≥ M N\geq M NM至少存在一种方案, 使得和 m o d    M = 0 \mod M=0 modM=0.

如果 N < M N<M N<M:

我们不妨设 f i , j f_{i,j} fi,j表示前 i i i个数是否能达到和在模意义下和为 j j j. A i = a i m o d    M A_i=a_i\mod M Ai=aimodM.

显然有 f i , ( j + A i )  mod M = { f i − 1 , j  or  f i − 1 , ( j + A i )  mod  M i f    j ≠ 0 t r u e i f    j = 0 f_{i,(j+A_i)\text{ mod M}}=\begin{cases}f_{i-1,j}\text{ or }f_{i-1,(j+A_i)\text{ mod }M}&if\;j\neq0\\true&if\;j=0\end{cases} fi,(j+Ai) mod M={fi1,j or fi1,(j+Ai) mod Mtrueifj=0ifj=0.

Code

# define Fast_IO std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
# include "unordered_map"
# include "algorithm"
# include "iostream"
# include "cstdlib"
# include "cstring"
# include "cstdio"
# include "vector"
# include "bitset"
# include "queue"
# include "cmath"
# include "map"
# include "set"

using namespace std;

const int maxm=1e6+10;
const int maxn=3e3+10;

int N,M,A[maxm],DP[maxn][maxn],Find;
unordered_map<int,int> LH;

int main(){
	static int i,j,Find;
	scanf("%d%d",&N,&M);
	for(i=1;i<=N;i++) scanf("%d",&A[i]);
	if(N>=M){
		printf("YES");
		return 0;
	}
	DP[1][A[1]%M]=true;
	for(i=2;i<=N;i++){
		for(j=0;j<M;j++){
			DP[i][(j+A[i])%M]=DP[i-1][j]|DP[i-1][(A[i]+j)%M];
		}DP[i][A[i]%M]=true;
	}puts(DP[N][0]?"YES":"NO");
	return 0;
}

Link

Link1: Daimayuan Online Judge 456 选数

Link2: CF577B Modulo Sum

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值