[COCI2013]DLAKAVAC

[COCI2013]DLAKAVAC

题目大意:

有一个长度为(m(mle1500))(01)(A),进行(k(kle10^{18}))次操作。一次操作完的串中若(A_i=1),当且仅当在原串中存在(jk\%m=i),且(A_j=A_k=1)。求所有操作完成后哪些位置为(1)

思路:

快速幂。时间复杂度(mathcal O(m^2log k))

源代码:

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
typedef long long int64;
inline int64 getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int64 x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
const int N=1500;
int64 k;
int m,n;
bool a[N],ans[N],tmp[N];
inline void mul(bool a[],bool b[]) {
	memset(tmp,0,sizeof tmp);
	for(register int i=0;i<m;i++) {
		for(register int j=0;j<m;j++) {
			tmp[(i*j)%m]|=a[i]&&b[j];
		}
	}
	std::copy(&tmp[0],&tmp[m],a);
}
int main() {
	k=getint(),m=getint(),n=getint();
	for(register int i=0;i<n;i++) {
		a[getint()]=true;
	}
	ans[1]=1;
	for(;k;k>>=1) {
		if(k&1) mul(ans,a);
		mul(a,a);
	}
	for(register int i=0;i<m;i++) {
		if(ans[i]) printf("%d ",i);
	}
	puts("");
	return 0;
}
原文地址:https://www.cnblogs.com/skylee03/p/9934060.html