[数学性质]luogu P1224 [NOI2013]向量内积
题面
https://www.luogu.com.cn/problem/P1224
分析
注意到k很小,只有2,3
对k值讨论
当k=2时,对于一个向量i,乘以之前向量的前缀和,如果之前向量与其乘积在模意义下都为1,值就为(i-1)%2,如果不为,则存在一个向量与其乘积在模意义下为0,O(nd)
当k=3时,余数为0,1,2,注意到对余数平方则余均为1,那么维护前缀平方和即可,O(nd^2)
当存在向量与其乘积为0时,找到对应向量的时间复杂度也为O(nd)
听他们说为了防止最坏情况(即一直到最后都没在前缀中找到和乘积为0的向量),需要randomshuffle一下序列。
代码
#include <iostream> #include <cstdio> using namespace std; const int N=1e5+10; const int D=101; int n,d,k; int a[N][D],t[N][D]; int main() { scanf("%d%d%d",&n,&d,&k); for (int i=1,x;i<=n;i++) { for (int j=1;j<=d;j++) scanf("%d",&a[i][j]),a[i][j]%=k; x=0; if (k==2) for (int j=1;j<=d;j++) (x+=t[0][j]*a[i][j])%=k,(t[0][j]+=a[i][j])%=k; else for (int j=1;j<=d;j++) for (int l=1;l<=d;l++) (x+=t[j][l]*a[i][j]*a[i][l])%=k,(t[j][l]+=a[i][j]*a[i][l])%=k; if (x!=(i-1)%k) for (int j=1;j<i;j++) { x=0; for (int l=1;l<=d;l++) (x+=a[i][l]*a[j][l])%=k; if (!x) return printf("%d %d",j,i),0; } } printf("-1 -1"); }
在日渐沉没的世界里,我发现了你。