2016CCPC网赛第二题。现场没出,好可惜。。
当时找到书上的板子了,不敢抄怕查重,然后就手写了一个高斯消元,数据量也挺小没用模版,直接模拟的,结果最后一直wa,找了一晚上原因竟然是数组开小了。。数组开小了,一直wa。。。不明嚼栗。。
蓝书161页原题。。
附代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
string s[3005];
int p[3005];
int nn = 0;
int a[3005];
int n;
int m;
const int MOD = 1000000007;
void init()
{
memset(p, 0, sizeof(p));
for(int i = 2; i <= 2000; ++i)
{
if(!p[i])
{
for(int j = i + i; j <= 2000; j += i)
{
p[j] = 1;
}
}
}
for(int i = 2; i <= 2000; ++i)
{
if(!p[i])
{
a[nn++] = i;
}
}
for(int i = 0; i <= 2001; ++i)
for(int j = 0; j <= 305; ++j)
s[i].push_back('0');
}
void solve(int j, long long x)
{
int i = 0;
while(i < nn)
{
if(x % a[i] == 0)
{
x /= a[i];
int tmp = s[i][j] - '0';
tmp = !tmp;
s[i][j] = '0' + tmp;
}
else
{
++i;
if(x == 1)
{
m = max(m, i);
return ;
}
}
}
}
bool cmp(const string &t1, const string &t2)
{
return t1 > t2;
}
void Xor(int ii, int res, int tar)
{
for(int i = ii; i < m; ++i)
{
s[tar][i] = '0' + ((s[tar][i] - '0') ^ (s[res][i] - '0'));
}
}
int Rank(int m, int n)
{
int i = 0, j = 0, k, r, u;
while(i < m && j < n)
{
r = i;
for(k = i; k < m; ++k)
if(s[k][j] == '1')
{
r = k;
break;
}
if(s[r][j] == '1')
{
if(r != i)
for(k = 0; k <= n; ++k)
{
swap(s[r][k], s[i][k]);
}
for(u = i + 1; u < m; ++u)
if(s[u][j] == '1')
{
for(k = i; k <= n; ++k)
{
s[u][k] = '0' + ((s[u][k] - '0') ^ (s[i][k] - '0'));
}
}
++i;
}
++j;
}
return i;
}
int main()
{
int T;
init();
scanf("%d", &T);
int kase = 0;
while(T--)
{
m = 0;
for(int i = 0; i <= 2001; ++i)
for(int j = 0; j <= 305; ++j)
s[i][j] = '0';
scanf("%d", &n);
for(int i = 0; i < n; ++i)
{
long long x;
scanf("%I64d", &x);
solve(i, x);
}
swap(n, m);
sort(s, s + n, cmp);
int ii = 0;
int ans;
// cout << "----------------" << endl;
while(true)
{
int flag = 0;
int jj;
for(int j = 0; j < m; ++j)
if(s[ii][j] != '0')
{
flag = 1;
jj = j;
break;
}
if(!flag || ii == n)
{
ans = ii;
break;
}
for(int i = ii + 1; i < n; ++i)
if(s[i][jj] != '0')
{
Xor(jj, ii, i);
}
++ii;
sort(s + ii, s + n, cmp);
// for(int i = 0; i < n; ++i)
// {
// for(int j = 0; j < m; ++j)
// cout << s[i][j] << " ";
// cout << endl;
// }
// cout << "----------------------------" << endl;
}
long long aa = 1;
for(int i = 1; i <= (m - ans); ++i)
{
aa *= 2;
aa %= MOD;
}
aa = (aa - 1 + MOD) % MOD;
printf("Case #%d:\n", ++kase);
printf("%I64d\n", aa);
}
}