NC17851. [NOI2013]向量内积
描述
输入描述
的第一行包含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 )=1C++(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"); }