列表

详情


NC17851. [NOI2013]向量内积

描述

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

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

输入描述

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

输出描述

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

示例1

输入:

3 5 2
1 0 1 0 1
1 1 0 1 0
0 1 0 1 1

输出:

2 3

说明:

(x1,x2 )=1
(x1,x3 )=1
(x2,x3 )=1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 501ms, 内存消耗: 78596K, 提交时间: 2022-11-09 18:05:10

#include <algorithm>
#include <array>
#include <bitset>
#include <cmath>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;

#define IO                       \
    ios::sync_with_stdio(false); \
    std::cin.tie(0);             \
    std::cout.tie(0)

#define debug(a) std::cerr << "\033[34m" << #a << ':' << a << "\033[0m" << std::endl

#define debugList(list)                        \
    std::cerr << "\033[34m" << #list << ": ["; \
    for (auto& e : list) {                     \
        std::cerr << e << ", ";                \
    }                                          \
    std::cerr << "\b\b]\033[0m" << endl

#define debugPair(label, val) std::cerr << "\033[34m" << #label << ':' << label << " " << #val << ':' << val << "\033[0m" << std::endl

template <typename T>
void debugPkg(const T& t) {
    std::cerr << "\033[34m" << t << "\033[0m" << std::endl;
}

template <typename T, typename... Args>
void debugPkg(const T& t, const Args&... pkg) {
    std::cerr << "\033[34m" << t << " ";
    debugPkg(pkg...);
}

#define testOut(a) std::cerr << "\033[32m" << a << "\033[0m" << std::endl

template <typename _Ty1, typename _Ty2>
ostream& operator<<(ostream& out, const pair<_Ty1, _Ty2>& pr) {
    out << "[" << pr.first << ", " << pr.second << "]";
    return out;
}

const int inf = 0x3f3f3f3f;
const long long llinf = (long long)0x3f3f3f3f3f3f3f3f;
const long long MOD = (long long)1e9 + 7LL;
const int MAXN = (int)1e6 + 5;

int a[MAXN][200], pre[MAXN];

void solve() {
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cin >> a[i][j];
            a[i][j] %= k;
        }
    }

    for (int i = 1; i <= n; ++i) {
        int res = 0;
        if (k == 3) {
            for (int j = 1; j <= m; ++j) {
                for (int p = 1; p <= m; ++p) {
                    int pos = (j - 1) * m + p;
                    res = (res + pre[pos] * a[i][j] * a[i][p]) % k;
                }
            }
        } else {
            for (int j = 1; j <= m; ++j) {
                res = (res + pre[j] * a[i][j]) % k;
            }
        }

        if (res % k != (i - 1) % k) {
            for (int j = 1; j < i; ++j) {
                int tmp = 0;
                for (int p = 1; p <= m; ++p) {
                    tmp = (tmp + a[j][p] * a[i][p] % k) % k;
                }
                if (tmp == 0) {
                    cout << j << ' ' << i << endl;
                    return;
                }
            }
        }

        if (k == 3) {
            for (int j = 1; j <= m; ++j) {
                for (int p = 1; p <= m; ++p) {
                    int pos = (j - 1) * m + p;
                    pre[pos] = (pre[pos] + a[i][j] * a[i][p] % k) % k;
                }
            }
        } else {
            for (int j = 1; j <= m; ++j) {
                pre[j] = (pre[j] + a[i][j]) % k;
            }
        }
    }
    cout << "-1 -1" << endl;
}

int main() {
    IO;
    int t = 1;
    // cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 400ms, 内存消耗: 48572K, 提交时间: 2022-10-15 16:37:46

#include<bits/stdc++.h>
using namespace std;
int x[123456][123], s[123], ss[123][123];
int check(int a, int b, int m, int mod){
	int ans = 0, i;
	for(i = 1;i <= m;i++)ans += x[a][i] * x[b][i];
	return ans % mod;
}
int solve(int n, int m, int mod){
	int ans = 0, i, j;
	if(mod == 2)for(i = 1;i <= m;i++)ans ^= x[n][i] & s[i],s[i] ^= x[n][i];
	else for(i = 1;i <= m;i++)for(j = 1;j <= m;j++)ans += ss[i][j] * x[n][i] * x[n][j],ss[i][j] = (ss[i][j] + x[n][i] * x[n][j]) % mod;
	return ans % mod;
}
int main(){
	int n, m, mod, i, j;
	scanf("%d%d%d", &n, &m, &mod);
	for(i = 1;i <= n;i++)for(j = 1;j <= m;j++){
		scanf("%d", &x[i][j]);
		x[i][j] %= mod;
	}
    for(i = 1;i <= n;i++)if(solve(i, m, mod) != (i - 1) % mod)for(j = 1;j < i;j++)if(!check(i, j, m, mod)){
        printf("%d %d", j, i);
        return 0;
    }
    printf("-1 -1");
} 

上一题