zoukankan      html  css  js  c++  java
  • 3243: [Noi2013]向量内积

    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.
    View Code
  • 相关阅读:
    .NET 云原生架构师训练营(模块二 基础巩固 MongoDB API实现)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 问答系统)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 聚合)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 更新和删除)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 写入和查询)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 介绍和基础)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 EF Core 更新和迁移)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 EF Core 查询)--学习笔记
    动态路由里,将component字符串改变为路由懒加载方法
    渗透小记
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3788313.html
Copyright © 2011-2022 走看看