結果

問題 No.3400 Nana's Plus Permutation Game (7 + 7) ÷ 7
コンテスト
ユーザー こめだわら
提出日時 2025-12-09 00:15:20
言語 C++23
(gcc 13.3.0 + boost 1.89.0)
結果
AC  
実行時間 848 ms / 2,777 ms
コード長 4,306 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 4,271 ms
コンパイル使用メモリ 313,828 KB
実行使用メモリ 25,996 KB
平均クエリ数 12907.31
最終ジャッジ日時 2025-12-09 00:16:22
合計ジャッジ時間 60,179 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 77
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;

#define rep(i,n) for(ll i=0;i<n;++i)
#define all(a) (a).begin(),(a).end()
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
template<class T> T div_floor(T a, T b) { return a / b - ((a ^ b) < 0 && a % b); }
template<class T> T div_ceil(T a, T b) { return a / b + ((a ^ b) > 0 && a % b); }
template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }
template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }

template<typename T>
ostream &operator<<(ostream &os, const vector<T> &a){
	if (a.empty()) return os;
	os << a.front();
	for (auto e : a | views::drop(1)){
		os << ' ' << e;
	}
	return os;
}

void dump(auto ...vs){
	((cout << vs << ' '), ...) << endl;
}

bool local=false;
vector<ll> ansP;

void solve() {
	ll N;
	cin>>N;
	if (local){
		ansP=vector<ll>(N,-1);
		rep(i,N){
			cin>>ansP[i];
		}
	}
	ll query_num=0;
	auto query=[&](ll i,ll j){
		assert (i!=j);
		query_num++;
		assert(query_num<3*N);
		cout<<"1 "<<i+1<<' '<<j+1<<endl;
		ll k=-1;
		if (local){
			ll s=ansP[i]+ansP[j];
			rep(a,N){
				if (ansP[a]==s){
					k=a+1;
					break;
				}
			}
		}
		else{
			cin>>k;
		}
		k--;
		if (k<0)k++;
		return k;
	};
	auto answer=[&](vector<ll> P){
		cout<<2;
		rep(i,N){
			cout<<' ';
			cout<<P[i];
		}
		cout<<endl;
		if (local){
			assert(P==ansP);
		}
		return;
	};
	ll base_i=-1;
	rep(i,N-1){
		ll r=query(i,i+1);
		if (r>=0){
			base_i=i;
			break;
		}
	}
	if (base_i==-1){
		ll r=query(N-1,0);
		if (r>=0){
			base_i=N-1;
		}
	}
	assert(base_i>=0);
	vector<ll> nxt(N,-1);
	rep(j,N){
		if (j==base_i)continue;
		nxt[j]=query(base_i,j);
	}
	vector<bool> is_start(N,true);
	rep(i,N){
		if (nxt[i]>=0){
			is_start[nxt[i]]=false;
		}
	}
	vector<vector<ll>> com;
	rep(i,N){
		if (i==base_i)continue;
		if (is_start[i]){
			vector<ll> c;
			ll ni=i;
			while (ni>=0){
				c.push_back(ni);
				ni=nxt[ni];
			}
			com.push_back(c);
		}
	}
	sort(all(com),[](vector<ll> a,vector<ll> b){
		return a.size()>b.size();
	});
	if (com.size()>=2){
		if (com[com.size()-1].size()==com[com.size()-2].size()){
			com.push_back({});
		}
	}
	reverse(all(com.back()));
	com.back().push_back(base_i);
	reverse(all(com.back()));
	// for (auto i:com){
	// 	dump(i);
	// }
	auto divide_com=[&](vector<vector<ll>> &C){
		ll B=C.size();
		vector<ll> D(N);
		rep(i,B){
			for (ll j:C[i]){
				D[j]=i;
			}
		}
		ll v=0;
		vector<ll> nxt(B,-1);
		vector<bool> over(B,false);
		rep(i,B){
			if (i==0){
				continue;
			}
			else{
				ll r=query(C[i][0],C[0][0]);
				if (r!=C[D[r]][0]){
					over[i]=true;
					v++;
				}
				nxt[i]=D[r];
			}
		}
		vector<bool> start_nxt(N,true);
		rep(i,B){
			if (nxt[i]>=0){
				start_nxt[nxt[i]]=false;
			}
		}
		rep(i,B){
			if (start_nxt[i]){
				nxt[0]=i;
				if (C[i].size()>1){
					ll r=query(C[0][0],C[0][1]);
					if (r==-1 or r!=C[D[r]][1]){
						over[0]=true;
						v++;
					}
				}
				break;
			}
		}
		vector<bool> used(B,false);
		vector<vector<ll>> nc;
		rep(i,B){
			if (used[i])continue;
			ll ni=i;
			ll now=0;
			vector<pair<ll,ll>> a;
			while (true){
				used[ni]=true;
				a.emplace_back(ni,now);
				now+=v;
				if (over[ni]){
					now-=B;
				}
				ni=nxt[ni];
				if (used[ni])break;
			}
			vector<pair<ll,ll>> L;
			ll idx=0;
			while (true){
				bool flag=false;
				for (auto [ai,av]:a){
					if (idx<C[ai].size()){
						L.emplace_back(av+B*idx,C[ai][idx]);
					}
					else{
						flag=true;
					}
				}
				if (flag)break;
				idx++;
			}
			sort(all(L));
			vector<ll> ncc;
			for (auto [v,i]:L){
				ncc.push_back(i);
			}
			nc.push_back(ncc);
		}
		sort(all(nc),[](vector<ll> a,vector<ll> b){
			return a.size()>b.size();
		});
		swap(C,nc);
		return;
	};
	while (com.size()>=2){
		divide_com(com);
		// for (auto i:com){
		// 	dump(i);
		// }
	}
	assert (com[0].size()==N);
	vector<ll> P(N);
	rep(i,N){
		P[com[0][i]]=i+1;
	}
	answer(P);
	return;
}


int main() {
	cin.tie(0)->sync_with_stdio(0);
	ll T=1;
	cin>>T;
	while (T--){
		solve();
	}
	return 0;
}
0