洛谷题面传送门

一道很神的随机化。

首先由于我们要求向量点乘 \(\bmod k\) 的值,因此我们可以将所有 \(x_{i,j}\) 都模上 \(k\),显然该操作不影响结果正确性。

注意到这里的 \(d\) 与 \(n\) 不同阶,这也就暗示我们要找到一个复杂度重心偏向 \(d\) 的算法,首先考虑 \(k=2\) 的情形,我们考虑依次枚举所有向量并维护它们的前缀和 \(\vec{S}\),对于每个向量 \(\vec{x_i}\) 我们求出 \(\vec{S}·\vec{x_i}\bmod k\) 的值——显然如果对于所有 \(j<i\),\(\vec{x_i}·\vec{x_j}\) 都不是 \(k\) 的倍数,那么应有 \(\vec{S}·\vec{x_i}\equiv i-1\pmod{k}\),因此如果我们发现上式不成立那么必然 \(\exists j<i,\vec{x_i}·\vec{x_j}\bmod k=0\),于是我们再 \(\mathcal O(nd)\) 地 check 一遍即可。

接下来考虑 \(k=3\) 的情形,由于任意两个向量 \(\vec{u}·\vec{v}\bmod 3\) 可能得到 \(0,1,2\) 三种可能,因此如果 \(\vec{S}·\vec{x_i}\not\equiv i-1\pmod{k}\) 并不能得出 \(\exists j<i,\vec{x_i}·\vec{x_j}\bmod k=0\),上述 solution 也就不能简简单单地推广到 \(k=3\) 的情形,不过发现 \(1,2\) 平方一下都能得到 \(1\),因此考虑求出 \(\sum\limits_{j=1}^{i-1}(\vec{x_j}·\vec{x_i})^2\)——该式子可以写成 \(\sum\limits_{j=1}^{i-1}\vec{x_j}·\vec{x_i}^{T}·\vec{x_j}^{T}·\vec{x_i}=\sum\limits_{j=1}^{i-1}\vec{x_j}·\vec{x_j}^{T}·\vec{x_i}^{T}·\vec{x_i}\),维护矩阵 \(A=\sum\limits_{j=1}^{i-1}\vec{x_j}·\vec{x_j}^T\) 即可 \(\mathcal O(d^2)\) 求出上述值,这部分复杂度 \(\mathcal O(nd^2)\)。

但是很显然在上述过程中我们用的只是必要条件,也就是说如果我们没有找到某个 \(i\) 满足 \(\vec{S}·\vec{x_i}\not\equiv i-1\pmod{k}\),并不意味着不存在符合条件的两个向量 \(i,j\),反例随便举,比如:

3 2 2
1 1
1 0
0 0

不过注意到在单次过程中,我们找不到符合条件的两个向量 \(\vec{x_i},\vec{x_j}\) 的概率是很小的,因此考虑随机化,每次把向量集合 random_shuffle 一下,然后重复上面的步骤即可,这样即可通过此题。

const int MAXN=1e5;
const int MAXM=100;
int n,m,k,a[MAXN+5][MAXM+5];
bool check(int x,int y){
int sum=0;
for(int i=1;i<=m;i++) sum+=a[x][i]*a[y][i];
return sum%k==0;
}
int b[MAXM+5],c[MAXM+5][MAXM+5],p[MAXN+5];
int work(int x){
if(k==2){
int sum=0;
for(int i=1;i<=m;i++) sum+=b[i]*a[x][i];
for(int i=1;i<=m;i++) b[i]^=a[x][i];
return sum%k;
} else {
int sum=0;
for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) sum+=c[i][j]*a[x][i]*a[x][j];
for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) c[i][j]=(c[i][j]+a[x][i]*a[x][j])%k;
return sum%k;
}
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);a[i][j]%=k;
}
for(int i=1;i<=n;i++) p[i]=i;
for(int t=1;t<=8;t++){
memset(b,0,sizeof(b));memset(c,0,sizeof(c));
random_shuffle(p+1,p+n+1);
for(int i=1;i<=n;i++) if(work(p[i])!=(i-1)%k){
for(int j=1;j<i;j++) if(check(p[i],p[j])){
printf("%d %d\n",min(p[i],p[j]),max(p[i],p[j]));return 0;
} assert(0);
}
} puts("-1 -1");
return 0;
}

洛谷 P1224 - [NOI2013] 向量内积(随机化)的更多相关文章

  1. P1224 [NOI2013]向量内积

    传送门 发现这个内积和矩乘有点像,考虑构造一个 $n$ 行 $m$ 列的矩阵 $A$,每一行都是一个题目给定的 $m$ 维向量 设 $B=AA^T$ ,其中 $A^T$ 为 $A$ 的转置矩阵,那么对 ...

  2. luogu P1224 [NOI2013]向量内积

    传送门 挺有意思的一道题 暴力60就是枚举每个向量暴力check,随机选向量就能多骗一些分 然后两个向量内积要模\(k\)为\(0\),那么如果全部不为\(0\)就不合法.先考虑\(k=2\),对于向 ...

  3. 【BZOJ-3243】向量内积 随机化 + 矩阵

    3243: [Noi2013]向量内积 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1249  Solved:  ...

  4. 【fake题解】[NOI2013]向量内积

    [fake题解][NOI2013]向量内积 做法1 大暴力.哪里不会T哪里. 做法2 所有数都%=k不影响结果.(废话 k的取值只有2和3,所以肯定是要分类讨论的.k=2肯定简单些啦. k=2 出现的 ...

  5. 洛谷 P2503 [HAOI2006]均分数据 随机化贪心

    洛谷P2503 [HAOI2006]均分数据(随机化贪心) 现在来看这个题就是水题,但模拟赛时想了1个小时贪心,推了一堆结论,最后发现贪心做 不了, 又想了半个小时dp 发现dp好像也做不了,在随机化 ...

  6. [Noi2013]向量内积

    来自FallDream的博客,未经允许,请勿转载,谢谢. 两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即: $\sum_{i=1 ...

  7. 洛谷P1224 向量内积

    什么毒瘤...... 题意:给定n个d维向量,定义向量a和b的内积为 求是否存在两个向量使得它们的内积为k的倍数,并给出任一种方案.k <= 3. 解:很容易想到一个暴力是n2d的.显然我们不能 ...

  8. UOJ#121. 【NOI2013】向量内积 随机化算法,矩阵

    原文链接www.cnblogs.com/zhouzhendong/UOJ121.html 前言 完蛋了我越来越菜了贺题都不会了. 题解 $O(n ^ 2 d) $ 暴力送 60 分. Bitset 优 ...

  9. BZOJ3243 NOI2013向量内积(随机化)

    考虑奇技淫巧. 首先是k=2.对向量维护一个前缀和,每次将当前向量与前缀和点乘.如果点乘结果不等于i-1&1,说明当前向量至少和之前的某个向量的数量积是2的倍数,暴力找就可以了.当然等于i-1 ...

随机推荐

  1. Golang通脉之接口

    接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节. 接口类型 在Go语言中接口(interface)是一种类型,一种抽象的类型. interface是 ...

  2. 网络摄像机中的IR-CUT详解

    自然界存在着各种波长的光线,通过折射人眼能看到不同颜色的光线,这就是光线的波长不同所导致的.其实还有许多光线是人眼看不到的,人眼识别光线的波长范围在320nm-760nm之间,超过760nm的光线人眼 ...

  3. 【做题记录】CF1428E Carrots for Rabbits—堆的妙用

    CF1428E Carrots for Rabbits 题意: 有 \(n\) 个萝卜,每个萝卜的初始大小为 \(a_i\) .现在要把这些萝卜切为为 \(k\) 个.吃每一个萝卜的时间为这个萝卜的大 ...

  4. 『学了就忘』Linux基础 — 13、Linux系统的分区和格式化

    目录 1.Linux系统的分区 (1)磁盘分区定义 (2)两种分区表形式 (3)MBR分区类型 2.Linux系统的格式化 (1)格式化定义 (2)格式化说明 1.Linux系统的分区 (1)磁盘分区 ...

  5. Android 服务名称规则invalid service name 限制16字符以内

    今天调试网络服务的时候为了区分,修改了原有服务名称,同时新增了两个服务. 系统运行的时候报错找不到对应的服务 init: no such service 'wpa_supplicant_common' ...

  6. 两个栈实现队列 牛客网 剑指Offer

    两个栈实现队列 牛客网 剑指Offer 题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. class Solution: def __init__(sel ...

  7. Python 模块 itertools

    python 2.6 引入了itertools模块,使得排列组合的实现非常简单: import itertools 有序排列:e.g., 4个数内选2个排列: >>> print l ...

  8. K8S在线部署含Dashborad

    参考文章 https://www.kubernetes.org.cn/5462.html 前言 Kubernetes作为容器编排工具,简化容器管理,提升工作效率而颇受青睐.很多新手部署Kubernet ...

  9. java中的泛型设计

    1.为什么要使用泛型程序设计 ArrayList<String> files = new ArrayList<>() 等价于 var files = new ArrayList ...

  10. 这些年我@yangbodong22011参与的开源

    2020年第一天,水一篇博客,对新年起码的尊重.这里记录下我参与的开源项目情况. Talk is cheap. Show me the code Linus Torvalds Jedis PR:htt ...