【GDOI2013模拟1】病毒传播
这题是个类似矩乘的东西。。。
我们要求的是第K天的感染人数。
然后我们可以证明出来这个满足结合律(易得(a * b) * b=a * (b * b))
而题目求的就是bk,所以我们就可以像快速幂一样求bk
O(log(k)*n2)
所以就可以用矩乘啦。
上标:
#include<cstdio>
#include<cstring>
#define N 1510
using namespace std;
int m,a[N],s[N],bz[N],tot=0;
long long K;
inline int read()
{
int x=0; char c=getchar();
while (c<'0' || c>'9') c=getchar();
while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x;
}
int main()
{
freopen("virus.in","r",stdin);
// freopen("virus.out","w",stdout);
scanf("%lld",&K),m=read(),a[0]=read();
for (int i=1;i<=a[0];i++) a[i]=read();
while (K)
{
if (K & 1)
{
if (!s[0])
{
memcpy(s,a,sizeof(a));
}
else
{
tot++;
for (int i=1;i<=a[0];i++)
for (int j=1;j<=s[0];j++)
bz[a[i]*s[j]%m]=tot;
s[0]=0;
for (int i=0;i<m;i++)
if (bz[i]==tot) s[++s[0]]=i;
}
}
tot++;
for (int i=1;i<=a[0];i++)
for (int j=1;j<=a[0];j++)
bz[a[i]*a[j]%m]=tot;
a[0]=0;
for (int i=0;i<m;i++)
if (bz[i]==tot) a[++a[0]]=i;
K>>=1;
}
for (int i=1;i<=s[0];i++)
printf("%d ",s[i]);
return 0;
}
转载需注明出处。