bzoj 3243: [Noi2013]向量内积 矩阵乘法

该博客探讨了NOI2013竞赛中关于向量内积的问题,指出原题解法的时间复杂度为O(N^2D),并提出了优化思路。在模2的情况下,通过计算向量点积的和来判断是否存在非零点积,再利用随机化策略提高解题正确率。对于模3的情况,通过考虑点积的平方来优化计算。最后给出了通过AC的代码片段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        这道题目中D应该是<=100。。

       我们可以把两个向量的点积看成1*d和d*1的矩阵相乘;那么我们将原始矩阵A转置得到A',A*A'[i,j]就是向量i*向量j的点积。

       但是这样是O(N^2D)的;考虑用一些黑科技。考虑mod=2时,假设对于i,我们求出i之前的所有向量与i的点积的和;如果所有的点积都>0即=1,那么显然点积的和对二取模=(i-1)%2;否则如果≠(i-1)%2,显然i与i前面的某一个向量的点积=0,我们O(ND)寻找答案即可。但是这样不一定能得到解,我们不妨随机打乱向量的顺序然后判断,这样至少是1-(1/2)^5的正确率了。。

       当mod=3时也是一样的,不过点积>0并不一定=1,但是注意到点积的平方>0则一定=1,把点积拆开来计算即可。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100005
#define M 101
#define rd ((rand_now=((long long)rand_now*20000909+2010527)%1000000009)/97)
using namespace std;

int n,m,mod,rand_now=1000003,a[N][M],q[N],b[M],c[M][M];
int read(){
	int x=0; char ch=getchar();
	while (ch<'0' || ch>'9') ch=getchar();
	while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
	return x;
}
bool check(int x,int y){
	int i,tmp=0;
	for (i=1; i<=m; i++) tmp+=a[x][i]*a[y][i];
	return !(tmp%mod);
}
int solve(int x){
	int ans=0,i,j;
	if (mod==2)
		for (i=1; i<=m; b[i]^=a[x][i],i++)
			ans^=b[i]&a[x][i];
	else
		for (i=1; i<=m; i++)
			for (j=1; j<=m; c[i][j]+=a[x][i]*a[x][j],j++)
				ans+=c[i][j]*a[x][i]*a[x][j];
	return ans%mod;
}
int main(){
	n=read(); m=read(); mod=read(); int i,j;
	for (i=1; i<=n; i++)
		for (j=1; j<=m; j++) a[i][j]=read()%mod;
	for (i=1; i<=n; i++) q[i]=i;
	int cas=7-mod;
	while (cas--){
		if (mod==2) memset(b,0,sizeof(b)); else memset(c,0,sizeof(c));
		for (i=2; i<=n; i++) swap(q[i],q[rd%(i-1)+1]);
		for (i=1; i<=n; i++) if (solve(q[i])!=(i-1)%mod)
			for (j=1; j<i; j++) if (check(q[i],q[j])){
				if (q[i]>q[j]) swap(i,j);
				printf("%d %d\n",q[i],q[j]); return 0;
			}
	}
	puts("-1 -1");
	return 0;
}


by lych

2016.5.23

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值