题意:一个
其中
现在有
解析:
一道矩阵乘法的题。。。
首先观察题目容易发现每天的魔法值由前一天得到,即存在递推关系,可以写出递推式:
其中
容易发现这是一个矩阵乘法的标准式子,我们可以直接求出
由于要多次询问,为了避免时间超限,我们预处理出
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctime>
#define INF 1e9
using namespace std;
const int maxn=110;
const double Pi=acos(-1.0);
template<class T>void read(T &x)
{
x=0;int f=0;char ch=getchar();
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return;
}
int n,m,q;
long long f[maxn],x[maxn],num[maxn];
struct matrix
{
bool a[maxn][maxn];
matrix()
{
memset(a,0,sizeof(a));
}
}p[41];
matrix multi(matrix u,matrix v)
{
matrix w;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
w.a[i][j]^=(u.a[i][k]&v.a[k][j]);
return w;
}
void power(long long u)
{
memset(num,0,sizeof(num));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(p[u].a[i][j])
num[i]=num[i]^x[j];
for(int i=1;i<=n;i++)
x[i]=num[i];
}
int main()
{
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++)
scanf("%lld",&f[i]);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
p[0].a[u][v]=p[0].a[v][u]=1;
}
for(int i=1;i<=31;i++)
p[i]=multi(p[i-1],p[i-1]);//预处理边矩阵的所有2次幂
for(int i=1;i<=q;i++)
{
for(int j=1;j<=n;j++)
x[j]=f[j];//初始化
long long y;
scanf("%lld",&y);
for(int j=0;j<=31;j++)
if(y&(1ll<<j))
power(j);//二进制拆分
printf("%lld\n",x[1]);
}
return 0;
}