兩個
現在有
輸入格式
第一行包含
接下來
輸出格式
包含兩個整數,用空格隔開。
如果存在兩個向量
若不存在這樣的向量組合,則輸出兩個
樣例一
input
3 5 2 1 0 1 0 1 1 1 0 1 0 0 1 0 1 1
output
2 3
explanation
限制與約定
測試點編號 |
|
|
|
|
---|---|---|---|---|
1 |
|
|
|
|
2 |
|
|
|
|
3 |
|
|
|
|
4 |
|
|
|
|
5 |
|
|
|
|
6 |
|
|
|
|
7 |
|
|
|
|
8 |
|
|
|
|
9 |
|
|
|
|
10 |
|
|
|
|
11 |
|
|
|
|
12 |
|
|
|
|
13 |
|
|
|
|
14 |
|
|
|
|
15 |
|
|
|
|
16 |
|
|
|
|
17 |
|
|
|
|
18 |
|
|
|
|
19 |
|
|
|
|
20 |
|
|
|
|
時間限制:
空間限制:
下載
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~隨機化~
隨機大法真是太神辣!!!
發現k==2或3,所以分開來做。
k==2時,我們發現內積只有0或1,所以我們用^運算i與之前的所有的內積是否與(i-1)%mod相等,不相等的話說明前面一定有與i得出的結果是1的,暴力尋找輸出即可。
但是顯然這樣判斷的誤差非常大,因爲這是取模下的運算。所以我們每次隨機順序,然後判斷它與之前的序列可不可行,只要判斷7-mod次即可。
3的情況同上。
改了半天模數最後發現是id寫成了a……
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int t,n,m,mod,a[100001][101],id[100001],las=1,b[100001],c[101][101];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int rand()
{
return las=(((long long)las*20000909+2010527)%1000000009)/97;
}
int sol(int u)
{
int ans=0;
if(mod==2) for(int i=1;i<=m;b[i]^=a[u][i],i++) ans^=b[i]&a[u][i];
else for(int i=1;i<=m;i++)
for(int j=1;j<=m;c[i][j]+=a[u][i]*a[u][j],j++)
ans+=c[i][j]*a[u][i]*a[u][j];
return ans%mod;
}
bool jud(int u,int v)
{
int now=0;
for(int i=1;i<=m;i++) now+=a[u][i]*a[v][i];
return !(now%mod);
}
int main()
{
n=read();m=read();mod=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) a[i][j]=read()%mod;
for(int i=1;i<=n;i++) id[i]=i;t=7-mod;
while(t--)
{
for(int i=2;i<=n;i++) swap(id[i],id[rand()%(i-1)+1]);
if(mod==2) memset(b,0,sizeof(b));
else memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
if(sol(id[i])!=(i-1)%mod)
for(int j=1;j<i;j++) if(jud(id[i],id[j]))
{
if(id[i]>id[j]) swap(id[i],id[j]);
printf("%d %d\n",id[i],id[j]);
return 0;
}
}
puts("-1 -1");
return 0;
}