P1224 [NOI2013] 向量内积

题意

给定 nd 维向量 ai,求一对合法的 i,j 使得 aiaj=0,其中 是向量点积,即 aiaj=p=1dai,paj,p

n105,d30,2k3

分析

考虑 k=2 怎么做。发现寻找一组解比较困难,考虑随机化。若无解,那么肯定满足 i,j,aiaj1。考虑随出一个集合 S,并让集合 S 外的 iS 内的所有向量分别做点积并求和(模 k 意义下),若总和为 |S|modk,则这个 i 肯定与 S 内的某个点点乘后合法,暴力 check 即可。不难发现每次做一遍成功率至少为 12,多做几次即可。复杂度 O(Knd)K 为随机次数。

考虑 k=3。这时无解,点积的结果可能为 12,相当的不好处理。但是注意到 12 平方后的结果模 3 意义下均为 1,把 p=1dai,paj,p 转化为 p=1dq=1dai,pai,qaj,paj,q,这样就转化为了 dd2k=2,就好处理了。复杂度 O(Knd2)

int n,m,d,k;
int a[maxn][maxm],b[maxms];
mt19937 rnd(time(0));
bool flag[maxn];
inline int get(int x,int y){
	return a[x][y/d]*a[x][y%d];
}
inline void solve_the_problem(){
	n=rd(),d=rd(),k=rd(),m=d*d;
	rep(i,1,n)rep(j,0,d-1)a[i][j]=rd()%k;
	rep(_,1,B){
		int tot=0;
		rep(i,1,n)flag[i]=rnd()%2,tot+=flag[i];
		rep(j,0,m-1)b[j]=0;
		rep(i,1,n)if(flag[i])rep(j,0,m-1)b[j]=(b[j]+get(i,j))%k;
		rep(i,1,n)if(!flag[i]){
			int sum=0;
			rep(j,0,m-1)sum=(sum+get(i,j)*b[j])%k;
			if(sum!=tot%k){
				rep(l,1,n)if(flag[l]){
					sum=0;
					rep(j,0,m-1)sum=(sum+get(i,j)*get(l,j))%k;
					if(!sum)return printf("%d %d",min(i,l),max(i,l)),void();
				}
			}
		}
	}
	printf("-1 -1");
}

作者:dcytrl

出处:https://www.cnblogs.com/dcytrl/p/18679589

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   dcytrl  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示