3243: [Noi2013]向量内积 - BZOJ

Description

两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即:

现有 n 个d 维向量x1,...,xn ,小喵喵想知道是否存在两个向量的内积为k的倍数。请帮助她解决这个问题
Input

第一行包含3个正整数n,d,k,分别表示向量的个数,维数以及待检测的倍数。
接下来n行每行有d个非负整数,其中第i行的第j个整数表示向量xi的第j维权值xi,j。
Output

包含两个整数,用空格隔开。
如果存在两个向量xp,xq的内积为k的整数倍,则输出两个向量的编号p与q(要求p<q)。如果存在多组这样的向量组合,输出其中任意一组即可。
若不存在这样的向量组合,则输出两个-1。
Sample Input
Sample Output
HINT

话说每次我都把题目复制一遍充字数2333

k=2时

我们把n个向量拼在一起,变成一个n*d的矩阵,设它为A,然后D=A*A’,A’为A的转置矩阵(行列互换),发现D[i,j]就表示向量i和向量j的内积

假设无解的话那么D矩阵除了对角线以外其他都是1,我们把无解的这个矩阵求出来设为C(只要求对角线),然后判断C和D是否相等,相等就无解

于是随机生成一个1*n的矩阵X判断X*A*A’是否等于X*C,假设不等于的话我们就找出不相等的那个位置,假设是第i个不相等,那就肯定存在一个j使得向量i与向量j的内积mod k=0

所以这个就暴力判断一下

k=3时

我们不能确定矩阵C的样子了,因为有三种情况0,1,2

但是我们发现1^2 mod 3=1,2^2 mod 3=1,所以我们让这个矩阵的元素都平方一下,那么矩阵C又变成了除了对角线其他都是1

但是前面又不好算了,其实也很好算,内积的平方拆开就变成了d^2维的向量的内积(空间存不下,直接照着式子算就行了)

其实随机生成矩阵不是很好,为0的话就没有用了,所以我直接用了全都是1的矩阵来跑答案

由于时间实在卡得太紧,我在Wikioi下了数据(可惜Wikioi没有spj)然后当提答题在bzoj上交了233

  1 const
  2     maxn=100100;
  3     maxd=110;
  4 var
  5     a:array[0..maxn,0..maxd]of longint;
  6     b,c,x,y:array[0..maxn]of longint;
  7     n,d,k:longint;
  8
  9 procedure work2;
 10 var
 11     i,j,k,s:longint;
 12 begin
 13     s:=0;
 14     for i:=1 to n do s:=s xor x[i];
 15     for i:=1 to n do c[i]:=s xor x[i] xor(x[i] and y[i]);
 16     for i:=1 to n do
 17         for j:=1 to d do
 18             b[j]:=b[j] xor (x[i] and a[i,j]);
 19     for i:=1 to d do x[i]:=b[i];
 20     for i:=1 to d do b[i]:=0;
 21     for i:=1 to d do
 22         for j:=1 to n do
 23             b[j]:=b[j] xor (x[i] and a[j,i]);
 24     for i:=1 to n do
 25         if b[i]<>c[i] then
 26         begin
 27             for j:=1 to n do
 28                 if i<>j then
 29                 begin
 30                     s:=0;
 31                     for k:=1 to d do
 32                         s:=s xor (a[i,k] and a[j,k]);
 33                     if s=0 then
 34                     begin
 35                         writeln(i,‘ ‘,j);
 36                         exit;
 37                     end;
 38                 end;
 39         end;
 40     writeln(‘-1 -1‘);
 41 end;
 42
 43 procedure work3;
 44 var
 45     i,j,k,s:longint;
 46 begin
 47     s:=0;
 48     for i:=1 to n do if y[i]>0 then y[i]:=1;
 49     for i:=1 to n do inc(s,x[i]);
 50     for i:=1 to n do c[i]:=(s-x[i]+x[i]*y[i])mod 3;
 51     for i:=1 to n do
 52         for j:=1 to d do
 53             for k:=1 to d do
 54                 inc(b[(j-1)*d+k],x[i]*a[i,j]*a[i,k]);
 55     for i:=1 to d*d do
 56         begin
 57             x[i]:=b[i]mod 3;
 58             b[i]:=0;
 59         end;
 60     for i:=1 to d do
 61         for j:=1 to d do
 62             for k:=1 to n do
 63                 inc(b[k],x[(i-1)*d+j]*a[k,i]*a[k,j]);
 64     for i:=1 to n do b[i]:=b[i]mod 3;
 65     for i:=1 to n do
 66         if b[i]<>c[i] then
 67         begin
 68             for j:=1 to n do
 69                 if i<>j then
 70                 begin
 71                     s:=0;
 72                     for k:=1 to d do
 73                         s:=s+a[i,k]*a[j,k];
 74                     if s mod 3=0 then
 75                     begin
 76                         writeln(i,‘ ‘,j);
 77                         exit;
 78                     end;
 79                 end;
 80         end;
 81     writeln(‘-1 -1‘)
 82 end;
 83
 84 procedure main;
 85 var
 86     i,j:longint;
 87 begin
 88     read(n,d,k);
 89     for i:=1 to n do
 90         for j:=1 to d do
 91             begin
 92                 read(a[i,j]);
 93                 a[i,j]:=a[i,j]mod k;
 94             end;
 95     for i:=1 to n do x[i]:=random(k);
 96     for i:=1 to n do
 97         for j:=1 to d do
 98             y[i]:=y[i]+a[i,j]*a[i,j];
 99     for i:=1 to n do y[i]:=y[i]mod k;
100     if k=2 then work2
101     else work3;
102 end;
103
104 begin
105     randomize;
106     main;
107 end.

3243: [Noi2013]向量内积 - BZOJ

时间: 2024-10-12 12:37:30

3243: [Noi2013]向量内积 - BZOJ的相关文章

[Noi2013]向量内积

来自FallDream的博客,未经允许,请勿转载,谢谢. 两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即: 现有 n 个d 维向量x1,...,xn ,小喵喵想知道是否存在两个向量的内积为k的倍数.请帮助她解决这个问题 k=2时 n<=20000 d<=100  k=3时n<=1000,d<=100 或者n<=100000 d<=30 把两个向量内积看作矩阵一个1*d的矩阵和d*1的矩阵相乘 那么k

BZOJ3243 [Noi2013]向量内积/UOJ121

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! Description 两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即: 现有 n 个d 维向量x1,...,xn ,小喵喵想知道是否存在两个向量的内积为k的倍数.请帮助她解决这个问题

【uoj121】 NOI2013—向量内积

http://uoj.ac/problem/121 (题目链接) 题意 给出${n}$个${d}$维向量,问是否有两个不同的向量的内积是${k}$的倍数. Solution 又卡了一上午常数,我弃了T_T. 右转题解→_→:llg 代码 // uoj121 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #inc

[BZOJ]3243 向量内积(Noi2016)

小C做了之后很有感觉的题目之一,但因为姿势不对调了很久. Description 两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即: 现有 n 个d 维向量x1,...,xn ,小喵喵想知道是否存在两个向量的内积为k的倍数.请帮助她解决这个问题. Input 第一行包含3个正整数n,d,k,分别表示向量的个数,维数以及待检测的倍数.接下来n行每行有d个非负整数,其中第i行的第j个整数表示向量xi的第j维权值xi,j. N<=1

编程题-最小向量内积-(1)

有两个向量v1=(x1,x2,...,xn)和v2=(y1,y2,...,yn),允许任意交换v1和v2各自的分量的顺序,计算v1和v2的内积x1y1+x2y2+...+xnyn的最小值 样例: 输入: n=3 v1=(1,3,?5) v2=(?2,4,1) 输出: -25 ( 令v1=(?5,1,3),v2=(4,1,?2) ) 首先我第一感觉就是,要保证最小, 1.如果在有正有负的情况下,那么有最大的正数乘以最小的负数, 2.如果都是正数,用最大的正数乘以最小的正数, 3.如果都是负数,用最

向量内积&amp;外积

一.向量的内积 1.1向量内积的定义 概括地说,向量的内积(点乘/点积/数量积)就是对两个向量执行点乘运算,即对这两个向量对应位一一相乘之后求和的操作,如下所示,对于向量a和向量b:                  a和b的点积公式为: 这里要求一维向量a和向量b的行列数相同.注意:点乘的结果是一个标量(数量而不是向量). 定义:两个向量a与b的内积为 a·b = |a||b|cos∠(a, b),特别地,0·a =a·0 = 0:若a,b是非零向量,则a与b正交的充要条件是a·b = 0.

NOI2015 UOJ122 向量内积

神题...... 还是大神讲得比较清晰~orz http://dffxtz.logdown.com/posts/197950-noi2013-vector-inner-product 启发题:poj3318 #include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #incl

向量内积的推导

基本式 几何 對稱性: . 線性函數:設 .固定  時, 而且 同樣道理,固定  時,

向量的内积和外积

向量的内积(点乘) 定义 概括地说,向量的内积(点乘/数量积).对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,如下所示,对于向量a和向量b:   a和b的点积公式为: 这里要求一维向量a和向量b的行列数相同.注意:点乘的结果是一个标量(数量而不是向量) 定义:两个向量a与b的内积为 a·b = |a||b|cos∠(a, b),特别地,0·a =a·0 = 0:若a,b是非零向量,则a与b****正交的充要条件是a·b = 0. 向量内积的性质: a^2 ≥ 0:当a^2