結果
| 問題 |
No.261 ぐるぐるぐるぐる!あみだくじ!
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2015-07-31 23:13:32 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 2,384 bytes |
| コンパイル時間 | 491 ms |
| コンパイル使用メモリ | 65,496 KB |
| 実行使用メモリ | 6,944 KB |
| 最終ジャッジ日時 | 2024-07-17 23:22:57 |
| 合計ジャッジ時間 | 1,473 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 37 |
ソースコード
// O(Q * N * log hoge)くらい?
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
typedef long long ll;
inline ll mod_inverse(ll a, ll m){
ll b = m, u = 1, v = 0;
while (b) {
ll t = a / b;
swap(a -= t * b, b);
swap(u -= t * v, v);
}
return (u % m + m) % m;
}
inline ll gcd(ll a, ll b){
if(b == 0){
return a;
}
return gcd(b, a % b);
}
pair<ll, ll> linear_congruence(const vector<ll>& A, const vector<ll>& B, const vector<ll>& M){
ll x = 0, m = 1;
for(int i=0;i<(int)A.size();i++){
ll a = A[i] * m, b = B[i] - A[i] * x, d = gcd(M[i], a);
if(b % d != 0){
return make_pair(0, -1);
}
ll t = b / d * mod_inverse(a / d, M[i] / d) % (M[i] / d);
x = x + m * t;
m *= M[i] / d;
}
return make_pair((x % m + m) % m, m);
}
int nxt[100];
int group_id[100], id[100];
int size[100];
void dfs(int now, int gid, int sz){
if(group_id[now] == gid){
size[gid] = sz;
return;
}
group_id[now] = gid;
id[now] = sz;
dfs(nxt[now], gid, sz + 1);
}
int main(){
memset(group_id, -1, sizeof(group_id));
int N, K;
cin >> N >> K;
for(int i=0;i<N;i++)nxt[i] = i;
for(int i=0;i<K;i++){
int X, Y;
cin >> X >> Y;
swap(nxt[X-1], nxt[Y-1]);
}
int gid = 0;
for(int i=0;i<N;i++){
if(group_id[i] == -1){
dfs(i, gid, 0);
++gid;
}
}
int Q;
cin >> Q;
while(Q--){
vector<int> A(N);
for(int i=0;i<N;i++){
cin >> A[i];
--A[i];
}
bool valid = true;
vector<ll> B(N), M(N);
for(int i=0;i<N;i++){
if(group_id[i] != group_id[A[i]]){
valid = false;
break;
}
int sz = size[group_id[i]];
B[i] = (id[A[i]] - id[i] + sz) % sz;
M[i] = sz;
}
if(!valid){
cout << -1 << endl;
continue;
}
auto res = linear_congruence(vector<ll>(N, 1), B, M);
if(res.second == -1){
cout << -1 << endl;
} else {
if(res.first == 0){
cout << res.second << endl;
} else {
cout << res.first << endl;
}
}
}
return 0;
}