题目:POJ2947.
题目大意:有
n
n
n种部件,每种部件生产一个的时间为
3
3
3~
9
9
9天.现在给定
m
m
m条记录,每个记录为某种
k
i
k_i
ki个部件的生产时间为星期几
s
i
s_i
si到星期几
t
i
t_i
ti,以及这
k
i
k_i
ki个部件的类型,问每种部件单个生产所需的时间.若无解输出"Inconsistent data.",有多组解输出"Multiple solutions.".
1
≤
n
,
m
≤
300
,
1
≤
∑
k
i
≤
1
0
4
1\leq n,m\leq 300,1\leq \sum k_i\leq 10^4
1≤n,m≤300,1≤∑ki≤104.
我们考虑设每个部件单个生产所需的时间为
x
i
x_i
xi,第
i
i
i条记录中第
j
j
j种部件的数量为
a
i
,
j
a_{i,j}
ai,j,那么可以列出一下方程组:
{
a
1
,
1
x
1
+
a
1
,
2
x
2
+
⋯
+
a
1
,
n
x
n
=
t
1
−
s
1
  
(
m
o
d
  
7
)
a
2
,
1
x
2
+
a
2
,
2
x
2
+
⋯
+
a
2
,
n
x
n
=
t
2
−
s
2
  
(
m
o
d
  
7
)
⋮
a
m
,
1
x
1
+
a
m
,
2
x
2
+
⋯
+
a
m
,
n
x
n
=
t
m
−
s
m
  
(
m
o
d
  
7
)
\left\{\begin{matrix} a_{1,1}x_1+a_{1,2}x_2+\cdots+a_{1,n}x_n=t_1-s_1\,\,(mod\,\,7)\\ a_{2,1}x_2+a_{2,2}x_2+\cdots+a_{2,n}x_n=t_2-s_2\,\,(mod\,\,7)\\ \vdots\\ a_{m,1}x_1+a_{m,2}x_2+\cdots+a_{m,n}x_n=t_m-s_m\,\,(mod\,\,7) \end{matrix}\right.
⎩⎪⎪⎪⎨⎪⎪⎪⎧a1,1x1+a1,2x2+⋯+a1,nxn=t1−s1(mod7)a2,1x2+a2,2x2+⋯+a2,nxn=t2−s2(mod7)⋮am,1x1+am,2x2+⋯+am,nxn=tm−sm(mod7)
这是一个典型的带模高斯消元,只是最后得到的解需要通过 ± 7 \pm7 ±7控制在 3 3 3~ 9 9 9范围内.
考虑高消时我们只需要把它消成一个三角矩阵,所以每当我们要处理第 i i i行第 j j j列的元素时,只需要把第 j j j列整一列的元素中,除了第 i i i行的全部消为 0 0 0.
这个时候若要消掉第 k k k行,我们只需要让第 k k k行同乘以 a [ i ] [ j ] a[i][j] a[i][j]且让第 i i i行同乘以 a [ k ] [ j ] a[k][j] a[k][j]来消元即可.
最后求解的时候由于系数不为 1 1 1,我们可以直接用费马小定理求解逆元.
解的情况判定与普通高斯消元类似.整个算法的时间复杂度为 O ( n 2 m ) O(n^2m) O(n2m).
注意,这种算法只能用于模数为质数的情况下.当模数为非质数时,这种算法会在同乘以一个数的地方出错.
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define Abigail inline void
typedef long long LL;
const int mod=7,N=300;
int n,m,flag,ans[N+9];
struct matrix{
int n,m,v[N+9][N+9];
}a;
int ri(){
int x=0;
char c=getchar();
for (;c<'0'||c>'9';c=getchar());
for (;c<='9'&&c>='0';c=getchar()) x=x*10+c-'0';
return x;
}
int rc(){
char c1=getchar(),c2;
while (c1<'A'||c1>'Z') c1=getchar();
c2=getchar();getchar();
if (c1=='T') return c2=='U'?2:4;
if (c1=='S') return c2=='A'?6:7;
if (c1=='M') return 1;
return c1=='F'?5:3;
}
int print(int x){
x%=mod;
if (x<3) x+=mod;
printf("%d ",x);
}
int power(int a,int k){
int s=1;
for (;k;k>>=1,a=a*a%mod)
if (k&1) s=s*a%mod;
return s;
}
int Gauss(matrix a){
int n=a.n,m=a.m,now=1,r,x,y;
for (int i=1;i<=n;++i){
for (r=now;r<=m;++r)
if (a.v[r][i]) break;
if (r>m) continue;
if (r^now) swap(a.v[r],a.v[now]);
x=a.v[now][i];
for (int j=1;j<=m;++j)
if (now^j){
y=a.v[j][i];
for (int k=1;k<=n+1;++k)
a.v[j][k]=((a.v[j][k]*x-a.v[now][k]*y)%mod+mod)%mod;
}
++now;
}
for (int i=1;i<=n;++i)
ans[i]=a.v[i][n+1]*power(a.v[i][i],mod-2)%mod;
for (int i=now;i<=m;++i)
if (a.v[i][n+1]) return 0;
return now<=n?2:1;
}
Abigail into(){
a=matrix();
a.n=n;a.m=m;
int k,x,y;
for (int i=1;i<=m;++i){
k=ri();x=rc();y=rc()-x+1;
a.v[i][n+1]=(y%mod+mod)%mod;
for (int j=1;j<=k;++j)
++a.v[i][ri()];
for (int j=1;j<=n;++j)
a.v[i][j]%=mod;
}
}
Abigail work(){
flag=Gauss(a);
}
Abigail outo(){
if (flag==0) puts("Inconsistent data.");
else if (flag==2) puts("Multiple solutions.");
else{
for (int i=1;i<=n;++i)
print(ans[i]);
puts("");
}
}
int main(){
while (2333){
n=ri();m=ri();
if (n+m==0) return 0;
into();
work();
outo();
}
}