Problem:
C: 一致
問題
長さ $N$ の数列 $a_i$ が与えられる。
次の条件を満たす整数 $K (1 \le K \le N)$ を全て出力せよ。
条件:
$a_1, \cdots, a_K$ をうまく並び替えると $a_{N-K+1}, \cdots, a_N$ と一致する。
制約
$1 \le N \le 10^5$
$1 \le a_i \le 10^9$
入力は全て整数
入力:
$N$
$a_1 \cdots a_N$
出力:
条件を満たす $K$ を昇順に空白区切りで出力せよ。また末尾に改行を出力せよ。
サンプル
サンプル入力 1
8
5 2 4 9 4 9 2 5
サンプル出力 1
1 2 4 6 7 8
サンプル入力 2
3
5 7 5
サンプル出力 2
1 2 3
サンプル入力 3
9
118 118 97 116 97 97 114 110 101
サンプル出力 3
9

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long

mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());

const int mod = 1e9 + 7;

int32_t main() {

    int n; cin >> n;

    vector <int> v(n + 1);
    for(int i = 1; i <= n; i++)
        cin >> v[i];

    map <int, int> mp;

    for(int i = 1; i <= n; i++)
        if(!mp.count(v[i]))
            mp[v[i]] = gen() % mod;

    int x = 0, y = 0;

    vector <int> ans;

    for(int i = 1; i <= n; i++) {
        int j = n - i + 1;

        (x += mp[v[i]]) %= mod;
        (y += mp[v[j]]) %= mod;

        if(x == y) ans.push_back(i);
    }

    for(int i = 0; i < ans.size(); i++)
        cout << ans[i] << (i < ans.size() - 1 ? " " : "\n");
}
accuracy: 1
time_ms: 60
memory_kb: 7116
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long

mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());

const int mod = 1e9 + 7;

int32_t main() {

    int n;
	cin >> n;

	vector <int> a(n);
	for(auto &i : a)
        cin >> i;

	unordered_map<int, long long> hash;
	mt19937 rnd((int)time(0));

	for(auto to : a)
        if(!hash.count(to))
            hash[to] = gen();

	vector <int> res;
	long long v1 = 0, v2 = 0;
	for(int i = 0; i < n; i++) {
		v1 += hash[a[i]];
		v2 += hash[a[n - 1 - i]];

		if (v1 == v2) res.push_back(i + 1);
	}

	int m = res.size();
	for(int i = 0; i < m; i++) {
		cout << res[i] << (i < m - 1 ? " " : "\n");
	}
}
accuracy: 1
time_ms: 30
memory_kb: 5844
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long

mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());

const int mod = 1e9 + 7;

int32_t main() {

    int n;
	cin >> n;

	vector <int> a(n);
	for(auto &i : a)
        cin >> i;

	unordered_map<int, long long> hash;
	mt19937 rnd((int)time(0));

	for(auto to : a)
        if(!hash.count(to))
            hash[to] = (long long)rnd();

	vector <int> res;
	long long v1 = 0, v2 = 0;
	for(int i = 0; i < n; i++) {
		v1 += hash[a[i]];
		v2 += hash[a[n - 1 - i]];

		if (v1 == v2) res.push_back(i + 1);
	}

	int m = res.size();
	for(int i = 0; i < m; i++) {
		cout << res[i] << (i < m - 1 ? " " : "\n");
	}
}
accuracy: 1
time_ms: 30
memory_kb: 5844
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long

mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());

const int mod = 1e9 + 7;

int32_t main() {

    int n;
	cin >> n;

	vector <int> a(n);
	for(auto &i : a)
        cin >> i;

	unordered_map<int, long long> hash;
	mt19937 rnd((int)time(0));

	vector <int> res;
	long long v1 = 0, v2 = 0;
	for(int i = 0; i < n; i++) {
		if (!hash.count(a[i])) {
			hash[a[i]] = (long long)rnd();
		}
		if (!hash.count(a[n - 1 - i])) {
			hash[a[n - 1 - i]] = (long long)rnd();
		}

		v1 += hash[a[i]];
		v2 += hash[a[n - 1 - i]];

		if (v1 == v2) res.push_back(i + 1);
	}

	int m = res.size();
	for(int i = 0; i < m; i++) {
		cout << res[i] << (i < m - 1 ? " " : "\n");
	}
}
accuracy: 1
time_ms: 30
memory_kb: 5780
final_rank: 3

code_snippet: #ifndef HIDDEN_IN_VISUAL_STUDIO // 折りたたみ用

// 警告の抑制
#define _CRT_SECURE_NO_WARNINGS

// ライブラリの読み込み
#include <bits/stdc++.h>
using namespace std;

// 型名の短縮
using ll = long long; // -2^63 ～ 2^63 = 9 * 10^18（int は -2^31 ～ 2^31 = 2 * 10^9）
using pii = pair<int, int>;	using pll = pair<ll, ll>;	using pil = pair<int, ll>;	using pli = pair<ll, int>;
using vi = vector<int>;		using vvi = vector<vi>;		using vvvi = vector<vvi>;
using vl = vector<ll>;		using vvl = vector<vl>;		using vvvl = vector<vvl>;
using vb = vector<bool>;	using vvb = vector<vb>;		using vvvb = vector<vvb>;
using vc = vector<char>;	using vvc = vector<vc>;		using vvvc = vector<vvc>;
using vd = vector<double>;	using vvd = vector<vd>;		using vvvd = vector<vvd>;
template <class T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>;
using Graph = vvi;

// 定数の定義
const double PI = 3.14159265359;
const double DEG = PI / 180.; // θ [deg] = θ * DEG [rad]
const vi dx4 = { 1, 0, -1, 0 }; // 4 近傍（下，右，上，左）
const vi dy4 = { 0, 1, 0, -1 };
const vi dx8 = { 1, 1, 0, -1, -1, -1, 0, 1 }; // 8 近傍
const vi dy8 = { 0, 1, 1, 1, 0, -1, -1, -1 };
const int INF = 1001001001; const ll INFL = 2002002002002002002LL;
const double EPS = 1e-10; // 許容誤差に応じて調整

// 入出力高速化
struct fast_io { fast_io() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); } } fastIOtmp;

// 汎用マクロの定義
#define all(a) (a).begin(), (a).end()
#define sz(x) ((int)(x).size())
#define distance (int)distance
#define Yes(b) {cout << ((b) ? "Yes" : "No") << endl;}
#define rep(i, n) for(int i = 0, i##_len = int(n); i < i##_len; ++i) // 0 から n-1 まで昇順
#define repi(i, s, t) for(int i = int(s), i##_end = int(t); i <= i##_end; ++i) // s から t まで昇順
#define repir(i, s, t) for(int i = int(s), i##_end = int(t); i >= i##_end; --i) // s から t まで降順
#define repe(v, a) for(const auto& v : (a)) // a の全要素（変更不可能）
#define repea(v, a) for(auto& v : (a)) // a の全要素（変更可能）
#define repb(set, d) for(int set = 0; set < (1 << int(d)); ++set) // d ビット全探索（昇順）
#define repp(a) sort(all(a)); for(bool a##_perm = true; a##_perm; a##_perm = next_permutation(all(a))) // a の順列全て（昇順）
#define repit(it, a) for(auto it = (a).begin(); it != (a).end(); ++it) // イテレータを回す（昇順）
#define repitr(it, a) for(auto it = (a).rbegin(); it != (a).rend(); ++it) // イテレータを回す（降順）
#define smod(n, m) ((((n) % (m)) + (m)) % (m)) // 非負mod
#define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());} // 重複除去

// 汎用関数の定義
template <class T> inline ll pow(T n, int k) { ll v = 1; rep(i, k) v *= n; return v; }
template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // 最大値を更新（更新されたら true を返す）
template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // 最小値を更新（更新されたら true を返す）

// 演算子オーバーロード
template <class T, class U> inline istream& operator>> (istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template <class T, class U> inline ostream& operator<< (ostream& os, const pair<T, U>& p) { os << "(" << p.first << "," << p.second << ")"; return os; }
template <class T, class U, class V> inline istream& operator>> (istream& is, tuple<T, U, V>& t) { is >> get<0>(t) >> get<1>(t) >> get<2>(t); return is; }
template <class T, class U, class V> inline ostream& operator<< (ostream& os, const tuple<T, U, V>& t) { os << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << ")"; return os; }
template <class T, class U, class V, class W> inline istream& operator>> (istream& is, tuple<T, U, V, W>& t) { is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t); return is; }
template <class T, class U, class V, class W> inline ostream& operator<< (ostream& os, const tuple<T, U, V, W>& t) { os << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << "," << get<3>(t) << ")"; return os; }
template <class T> inline istream& operator>> (istream& is, vector<T>& v) { repea(x, v) is >> x; return is; }
template <class T> inline ostream& operator<< (ostream& os, const vector<T>& v) { repe(x, v) os << x << " "; return os; }
template <class T> inline ostream& operator<< (ostream& os, const set<T>& s) { repe(x, s) os << x << " "; return os; }
template <class T> inline ostream& operator<< (ostream& os, const set<T, greater<T>>& s) { repe(x, s) os << x << " "; return os; }
template <class T> inline ostream& operator<< (ostream& os, const unordered_set<T>& s) { repe(x, s) os << x << " "; return os; }
template <class T, class U> inline ostream& operator<< (ostream& os, const map<T, U>& m) { repe(p, m) os << p << " "; return os; }
template <class T, class U> inline ostream& operator<< (ostream& os, const unordered_map<T, U>& m) { repe(p, m) os << p << " "; return os; }
template <class T> inline ostream& operator<< (ostream& os, stack<T> s) { while (!s.empty()) { os << s.top() << " "; s.pop(); } return os; }
template <class T> inline ostream& operator<< (ostream& os, queue<T> q) { while (!q.empty()) { os << q.front() << " "; q.pop(); } return os; }
template <class T> inline ostream& operator<< (ostream& os, deque<T> q) { while (!q.empty()) { os << q.front() << " "; q.pop_front(); } return os; }
template <class T> inline ostream& operator<< (ostream& os, priority_queue<T> q) { while (!q.empty()) { os << q.top() << " "; q.pop(); } return os; }
template <class T> inline ostream& operator<< (ostream& os, priority_queue_rev<T> q) { while (!q.empty()) { os << q.top() << " "; q.pop(); } return os; }
template <class T> inline vector<T>& operator--(vector<T>& v) { rep(_i_, sz(v)) --v[_i_]; return v; }

// 手元環境（Visual Studio）
#ifdef _MSC_VER
#define popcount (int)__popcnt // 全ビット中の 1 の個数
#define popcountll (int)__popcnt64
inline int lsb(unsigned int n) { unsigned long i; _BitScanForward(&i, n); return i; } // 最下位ビットの位置（0-indexed）
inline int lsbll(unsigned long long n) { unsigned long i; _BitScanForward64(&i, n); return i; }
inline int msb(unsigned int n) { unsigned long i; _BitScanReverse(&i, n); return i; } // 最上位ビットの位置（0-indexed）
inline int msbll(unsigned long long n) { unsigned long i; _BitScanReverse64(&i, n); return i; }
template <class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
#define dump(x) cout << "\033[1;36m" << (x) << "\033[0m" << endl;
#define dumps(x) cout << "\033[1;36m" << (x) << "\033[0m ";
#define dumpel(a) { int _i_ = -1; cout << "\033[1;36m"; repe(x, a) {cout << ++_i_ << ": " << x << endl;} cout << "\033[0m"; }
#define input_from_file(f) ifstream isTMP(f); cin.rdbuf(isTMP.rdbuf());
#define output_to_file(f) ofstream osTMP(f); cout.rdbuf(osTMP.rdbuf());
// 提出用（gcc）
#else
#define popcount (int)__builtin_popcount
#define popcountll (int)__builtin_popcountll
#define lsb __builtin_ctz
#define lsbll __builtin_ctzll
#define msb(n) (31 - __builtin_clz(n))
#define msbll(n) (63 - __builtin_clzll(n))
#define gcd __gcd
#define dump(x)
#define dumps(x)
#define dumpel(v)
#define input_from_file(f)
#define output_to_file(f)
#endif

#endif // 折りたたみ用


////-----------------AtCoder 専用-----------------
//#include <atcoder/all>
//using namespace atcoder;
//
//using mint = modint1000000007;
////using mint = modint998244353;
////using mint = modint; // mint::set_mod(m);
//
//template <class S, S(*op)(S, S), S(*e)()>ostream& operator<<(ostream& os, segtree<S, op, e> seg) { int n = seg.max_right(0, [](S x) {return true; }); rep(i, n) os << seg.get(i) << " "; return os; }
//template <class S, S(*op)(S, S), S(*e)(), class F, S(*mp)(F, S), F(*cp)(F, F), F(*id)()>ostream& operator<<(ostream& os, lazy_segtree<S, op, e, F, mp, cp, id> seg) { int n = seg.max_right(0, [](S x) {return true; }); rep(i, n) os << seg.get(i) << " "; return os; }
//istream& operator>> (istream& is, mint& x) { ll x_; is >> x_; x = x_; return is; }
//ostream& operator<< (ostream& os, const mint& x) { os << x.val(); return os; }
//using vm = vector<mint>;	using vvm = vector<vm>;		using vvvm = vector<vvm>;
////----------------------------------------------


int main() {
//	input_from_file("input.txt");
//	output_to_file("output.txt");
#ifdef LOCAL
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
    #else
//        freopen("express.in","r",stdin);
//        freopen("express.out","w",stdout);
    #endif

	int n;
	cin >> n;

	vi a(n);
	cin >> a;

	unordered_map<int, ll> hash;
	mt19937 rnd((int)time(0)); // 乱数生成器

	vi res;
	ll v1 = 0, v2 = 0;
	rep(i, n) {
		if (!hash.count(a[i])) {
			hash[a[i]] = (ll)rnd();
		}
		if (!hash.count(a[n - 1 - i])) {
			hash[a[n - 1 - i]] = (ll)rnd();
		}

		v1 += hash[a[i]];
		v2 += hash[a[n - 1 - i]];

		if (v1 == v2) res.push_back(i + 1);
	}

	int m = sz(res);
	rep(i, m) {
		cout << res[i] << (i < m - 1 ? " " : "\n");
	}
}
accuracy: 1
time_ms: 20
memory_kb: 5388
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <random>
#include <chrono>
#include <map>
using namespace std;
typedef long long ll;
// const ll INF64 = 1LL << 60;
const ll INF64 = ((1LL<<62)-(1LL<<31));  // 10^18より大きく、かつ2倍しても負にならない数
const int INF32 = 0x3FFFFFFF;  // =(2^30)-1 10^9より大きく、かつ2倍しても負にならない数
template<class T> inline bool chmin(T &a, T b) { if(a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T &a, T b) { if(a < b) { a = b; return true; } return false; }
#define YesNo(T) cout << ((T) ? "Yes" : "No") << endl;  // T:bool

// AOJ 2876
// https://onlinejudge.u-aizu.ac.jp/challenges/sources/VPC/RUPC/2876

/*
 * 集合の一致なのでZobrist Hashを用いる。
 * ＞1.集合の要素にランダムな整数を割り当てる。
 * ＞2.集合のハッシュは割り当てられた整数をxorしたもの。
 * Aiが最大で10^9と大きいので、各値に事前にランダム値を割り当てるのは間に合わない。
 * mapを用いてランダム値を用意する。rnd()を参照。
 * 
 * 同じ値が集合に含まれる(多重集合)のため、xorではなく加算してハッシュとする。
 * ＞多重集合の場合、割り当てられた整数を偶数回xorすると0になってしまい、区別がつかない。
 * ＞xorではなく加算することでハッシュにできる。かんたん。
 */

// [lo,hi]の区間の乱数を返す(閉区間)
// 必要なincludeは以下2つ
//   #include <random>
//   #include <chrono>
// 型はlong longで決め打ちしている。(mt19937_64を使っており、生成される値は64bit)
// 参考：
//   https://betrue12.hateblo.jp/entry/2019/09/07/171628
//   https://zenn.dev/mafafa/articles/f1030c3a014d4e
//   https://ei1333.github.io/luzhiled/snippets/other/random-number-generator.html
//   https://yosupo.hatenablog.com/entry/2024/06/14/064913
//   https://rsk0315.hatenablog.com/entry/2020/09/02/164428
//   https://cpprefjp.github.io/reference/random/mt19937_64.html
//   https://cpprefjp.github.io/reference/random/uniform_int_distribution.html
long long rng_64(long long lo, long long hi) {
	// static std::random_device rd;  // random_deviceを使うのは避けた方が良い環境があるらしい
	// static std::mt19937_64 rng(rd());
	static auto seed = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();
	static std::mt19937_64 rng(seed);
	return std::uniform_int_distribution<long long>(lo, hi)(rng);  // [lo,hi]の範囲での乱数を生成
}

// 値nに対する乱数を返す
ll rng(ll n)
{
	static map<ll,ll> rng;
	if(rng.count(n) == 0) rng[n] = rng_64(0, INF64);  // 値nに対する乱数を初回生成

	return rng[n];
}

int main(void)
{
	int i;
	int N; cin >> N;
	vector<ll> a(N); for(i = 0; i < N; i++) {cin >> a[i];}
	vector<ll> sum(a.size()+1); for(int kk = 0; kk < (int)a.size(); kk++) {sum[kk+1] = sum[kk] + rng(a[kk]);}

	vector<int> ans;
	for(int k = 0; k < N; k++)  // [0,k] と [N-k-1,N-1]  -> [0,k+1) と [N-k-1,N)
	{
		ll tmp1 = sum[k+1] - sum[0];
		ll tmp2 = sum[N] - sum[N-k-1];
		if(tmp1 == tmp2) ans.push_back(k+1);
	}

	int sz_ = (int)ans.size();
	for(i = 0; i < sz_; i++) {
		cout << ans[i];
		if(i != sz_-1) cout << " ";
	}
	cout << endl;

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 7920
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <random>
#include <chrono>
#include <map>
using namespace std;
typedef long long ll;
// const ll INF64 = 1LL << 60;
const ll INF64 = ((1LL<<62)-(1LL<<31));  // 10^18より大きく、かつ2倍しても負にならない数
const int INF32 = 0x3FFFFFFF;  // =(2^30)-1 10^9より大きく、かつ2倍しても負にならない数
template<class T> inline bool chmin(T &a, T b) { if(a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T &a, T b) { if(a < b) { a = b; return true; } return false; }
#define YesNo(T) cout << ((T) ? "Yes" : "No") << endl;  // T:bool

// ABC*** https://atcoder.jp/contests/abc***

/*
 * 
 * 
 */

// [lo,hi]の区間の乱数を返す(閉区間)
// 必要なincludeは以下2つ
//   #include <random>
//   #include <chrono>
// 型はlong longで決め打ちしている。(mt19937_64を使っており、生成される値は64bit)
// 参考：
//   https://betrue12.hateblo.jp/entry/2019/09/07/171628
//   https://zenn.dev/mafafa/articles/f1030c3a014d4e
//   https://ei1333.github.io/luzhiled/snippets/other/random-number-generator.html
//   https://yosupo.hatenablog.com/entry/2024/06/14/064913
//   https://rsk0315.hatenablog.com/entry/2020/09/02/164428
//   https://cpprefjp.github.io/reference/random/mt19937_64.html
//   https://cpprefjp.github.io/reference/random/uniform_int_distribution.html
long long rng_64(long long lo, long long hi) {
	// static std::random_device rd;  // random_deviceを使うのは避けた方が良い環境があるらしい
	// static std::mt19937_64 rng(rd());
	static auto seed = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();
	static std::mt19937_64 rng(seed);
	return std::uniform_int_distribution<long long>(lo, hi)(rng);  // [lo,hi]の範囲での乱数を生成
}

ll rng(ll n)
{
	static map<ll,ll> rng;
	if(rng.count(n) == 0) rng[n] = rng_64(0, INF64);

	return rng[n];
}

int main(void)
{
	int i;
	int N; cin >> N;
	vector<ll> a(N); for(i = 0; i < N; i++) {cin >> a[i];}
	vector<ll> sum(a.size()+1); for(int kk = 0; kk < (int)a.size(); kk++) {sum[kk+1] = sum[kk] + rng(a[kk]);}

	vector<int> ans;
	for(int k = 0; k < N; k++)  // [0,k] と [N-k-1,N-1]  -> [0,k+1) と [N-k-1,N)
	{
		ll tmp1 = sum[k+1] - sum[0];
		ll tmp2 = sum[N] - sum[N-k-1];
		if(tmp1 == tmp2) ans.push_back(k+1);
	}

	int sz_ = (int)ans.size();
	for(i = 0; i < sz_; i++) {
		cout << ans[i];
		if(i != sz_-1) cout << " ";
	}
	cout << endl;

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 7924
final_rank: 15

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    map<int, ll> mp;
    auto rnd = [&](int x) -> ll {
        if (mp.find(x) == mp.end()) {
            mp[x] = myRand(1e12);
        }
        return mp[x];
    };
    ll s1 = 0, x1 = 0, s2 = 0, x2 = 0;
    vector<int> res;
    for (int i = 0; i < n; ++i) {
        s1 += rnd(a[i]);
        x1 ^= rnd(a[i]);
        s2 += rnd(a[n - 1 - i]);
        x2 ^= rnd(a[n - 1 - i]);
        if (s1 == s2 and x1 == x2) {
            res.push_back(i + 1);
        }
    }
    for (int i = 0; i < res.size(); ++i) {
        if (i) cout << " ";
        cout << res[i];
    }
    cout << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 6592
final_rank: 12

code_snippet: #line 1 "Library/src/debug.hpp"
#ifdef ONLINE_JUDGE
#define debug(x) void(0)
#else
#define _GLIBCXX_DEBUG
#define debug(x) std::cerr << __LINE__ << " : " << #x << " = " << (x) << std::endl
#endif

/**
 * @brief Debugger
*/
#line 2 "Library/src/stream.hpp"
#include <ctype.h>
#include <stdio.h>
#include <string>
#line 2 "Library/src/internal/type_traits.hpp"
#include <iostream>
#include <limits>
#include <numeric>
#include <typeinfo>
#include <cstdint>

namespace kyopro {
namespace internal {
template <typename... Args> struct first_enabled {};

template <typename T, typename... Args>
struct first_enabled<std::enable_if<true, T>, Args...> {
    using type = T;
};
template <typename T, typename... Args>
struct first_enabled<std::enable_if<false, T>, Args...>
    : first_enabled<Args...> {};
template <typename T, typename... Args> struct first_enabled<T, Args...> {
    using type = T;
};

template <typename... Args>
using first_enabled_t = typename first_enabled<Args...>::type;

template <int dgt, std::enable_if_t<dgt <= 128>* = nullptr> struct int_least {
    using type = first_enabled_t<std::enable_if<dgt <= 8, std::int8_t>,
                                 std::enable_if<dgt <= 16, std::int16_t>,
                                 std::enable_if<dgt <= 32, std::int32_t>,
                                 std::enable_if<dgt <= 64, std::int64_t>,
                                 std::enable_if<dgt <= 128, __int128_t>>;
};

template <int dgt, std::enable_if_t<dgt <= 128>* = nullptr> struct uint_least {
    using type = first_enabled_t<std::enable_if<dgt <= 8, std::uint8_t>,
                                 std::enable_if<dgt <= 16, std::uint16_t>,
                                 std::enable_if<dgt <= 32, std::uint32_t>,
                                 std::enable_if<dgt <= 64, std::uint64_t>,
                                 std::enable_if<dgt <= 128, __uint128_t>>;
};

template <int dgt> using int_least_t = typename int_least<dgt>::type;
template <int dgt> using uint_least_t = typename uint_least<dgt>::type;

template <typename T>
using double_size_uint_t = uint_least_t<2 * std::numeric_limits<T>::digits>;

template <typename T>
using double_size_int_t = int_least_t<2 * std::numeric_limits<T>::digits>;

struct modint_base {};
template <typename T> using is_modint = std::is_base_of<modint_base, T>;
template <typename T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;


// is_integral
template <typename T>
using is_integral_t =
    std::enable_if_t<std::is_integral_v<T> || std::is_same_v<T, __int128_t> ||
                   std::is_same_v<T, __uint128_t>>;
};  // namespace internal
};  // namespace kyopro

/**
 * @brief Type Traits
 * @see https://qiita.com/kazatsuyu/items/f8c3b304e7f8b35263d8
 */
#line 6 "Library/src/stream.hpp"

namespace kyopro {

inline void single_read(char& c) {
    c = getchar_unlocked();
    while (isspace(c)) c = getchar_unlocked();
}
template <typename T, internal::is_integral_t<T>* = nullptr>
inline void single_read(T& a) {
    a = 0;
    bool is_negative = false;
    char c = getchar_unlocked();
    while (isspace(c)) {
        c = getchar_unlocked();
    }
    if (c == '-') is_negative = true, c = getchar_unlocked();
    while (isdigit(c)) {
        a = 10 * a + (c - '0');
        c = getchar_unlocked();
    }
    if (is_negative) a *= -1;
}
template <typename T, internal::is_modint_t<T>* = nullptr>
inline void single_read(T& a) {
    long long x;
    single_read(x);
    a = T(x);
}
inline void single_read(std::string& str) noexcept {
    char c = getchar_unlocked();
    while (isspace(c)) c = getchar_unlocked();
    while (!isspace(c)) {
        str += c;
        c = getchar_unlocked();
    }
}
template<typename T>
inline void read(T& x) noexcept {single_read(x);}
template <typename Head, typename... Tail>
inline void read(Head& head, Tail&... tail) noexcept {
    single_read(head), read(tail...);
}

inline void single_write(char c) noexcept { putchar_unlocked(c); }
template <typename T, internal::is_integral_t<T>* = nullptr>
inline void single_write(T a) noexcept {
    if (!a) {
        putchar_unlocked('0');
        return;
    }
    if constexpr (std::is_signed_v<T>) {
        if (a < 0) putchar_unlocked('-'), a *= -1;
    }
    constexpr int d = std::numeric_limits<T>::digits10;
    char s[d + 1];
    int now = d + 1;
    while (a) {
        s[--now] = (char)'0' + a % 10;
        a /= 10;
    }
    while (now <= d) putchar_unlocked(s[now++]);
}
template <typename T, internal::is_modint_t<T>* = nullptr>
inline void single_write(T a) noexcept {
    single_write(a.val());
}
inline void single_write(const std::string& str) noexcept {
    for (auto c : str) {
        putchar_unlocked(c);
    }
}
template <typename T> inline void write(T x) noexcept { single_write(x); }
template <typename Head, typename... Tail>
inline void write(Head head, Tail... tail) noexcept {
    single_write(head);
    putchar_unlocked(' ');
    write(tail...);
}
template <typename... Args> inline void put(Args... x) noexcept {
    write(x...);
    putchar_unlocked('\n');
}
};  // namespace kyopro

/**
 * @brief Fast IO(高速入出力)
 */
#line 2 "Library/src/template.hpp"
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(x) std::begin(x), std::end(x)
#define popcount(x) __builtin_popcountll(x)
using i128 = __int128_t;
using ll = long long;
using ld = long double;
using graph = std::vector<std::vector<int>>;
using P = std::pair<int, int>;
constexpr int inf = std::numeric_limits<int>::max() / 2;
constexpr ll infl = std::numeric_limits<ll>::max() / 2;
const long double pi = acosl(-1);
constexpr int dx[] = {1, 0, -1, 0, 1, -1, -1, 1, 0};
constexpr int dy[] = {0, 1, 0, -1, 1, 1, -1, -1, 0};
template <typename T1, typename T2> constexpr inline bool chmax(T1& a, T2 b) {
    return a < b && (a = b, true);
}
template <typename T1, typename T2> constexpr inline bool chmin(T1& a, T2 b) {
    return a > b && (a = b, true);
}

/**
 * @brief Template
*/
#line 4 "a.cpp"
using namespace std;
using namespace kyopro;

using u64 = uint64_t;

int main() {
    int n;
    cin >> n;

    vector<int> a(n);
    rep(i, n) cin >> a[i];
    vector<int> b = a;
    reverse(all(b));

    unordered_map<int, int> mpa, mpb;
    rep(i, n) mpa[a[i]] = mpb[a[i]] = mpa[b[i]] = mpb[b[i]] = 0;
    int same = mpa.size();

    vector<int> ans;
    rep(k, n) {
        if (a[k] != b[k]) {
            if (mpa[a[k]] == mpb[a[k]]) --same;
            if (++mpa[a[k]] == mpb[a[k]]) ++same;

            if (mpa[b[k]] == mpb[b[k]]) --same;
            if (mpa[b[k]] == ++mpb[b[k]]) ++same;
        }
        if (same == mpa.size()) ans.emplace_back(k + 1);
    }
    rep(i, (int)ans.size()) cout << ans[i] << " \n"[i == (int)ans.size() - 1];
}
accuracy: 1
time_ms: 50
memory_kb: 7848
final_rank: 13

code_snippet: #include <bits/stdc++.h>
// #include <atcoder/all>
// // using mint = atcoder::modint998244353;
// using mint = atcoder::modint1000000007;
// using namespace atcoder;
using namespace std;

using ll = long long;
using vi = vector<int>;
// using vm = vector<mint>;
using vvi = vector<vi>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vpi = vector<pair<int,int>>;
using vpl = vector<pair<ll,ll>>;
#define rep(i,n) for (ll i = 0; i < n; i++)
#define replr(i,l,r) for (ll i = l; i < r; i++)
set<char> abc = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
const int inf =1e9;
const ll infl = 4e18;

template <typename T>
bool chmax(T &a, const T& b) {if (a < b) {a = b;  return true;}return false;}
template <typename T>
bool chmin(T &a, const T& b) {if (a > b) {a = b;  return true;}return false;}
template <typename T>
T max(vector<T> &v) {T m = 0;for (auto x : v) chmax(m, x);return m;}
template <typename T>
T min(vector<T> &v) {T m = inf;for (auto x : v) chmin(m, x);return m;}
template <typename T>
void print(vector<T> &v){for(auto x : v){cout<<x<<' ';}cout<<'\n';}
/*memo

*/

int main(){
    int N; cin >> N;
    vi A(N);rep(i,N) cin >> A[i];
    map<int,int> cnt;
    int n=0;
    vi ans;
    rep(i,N){
        if (cnt[A[i]]==0) n++;
        cnt[A[i]]++;
        if (cnt[A[N-i-1]]==1) n--;
        cnt[A[N-i-1]]--;
        if (n==0) ans.push_back(i+1);
    }
    rep(i,ans.size()){
        if (i!=ans.size()-1){
            cout << ans[i] << ' ';
        }
        else{
            cout << ans[i] << '\n';
        }
    }
}
accuracy: 1
time_ms: 60
memory_kb: 5780
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;

/* BOOST MULTIPRECISION
#include<boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
//*/

typedef long long ll;

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)

template <typename T> bool chmin(T &a, const T &b) {
	if (a <= b) return false;
	a = b;
	return true;
}

template <typename T> bool chmax(T &a, const T &b) {
	if (a >= b) return false;
	a = b;
	return true;
}

template <typename T> T max(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]);
	return ret;
}

template <typename T> T min(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]);
	return ret;
}

template <typename T> T sum(vector<T> &a){
	T ret = 0;
	for (int i=0; i<(int)a.size(); i++) ret += a[i];
	return ret;
}

// defcomp
template <typename T>
vector<T> compress(vector<T> &X) {
	vector<T> vals = X;
	sort(vals.begin(), vals.end());
	vals.erase(unique(vals.begin(), vals.end()), vals.end());
	return vals;
}
// -----



int main(){
	int n; cin >> n;
	vector<ll> a(n);
	rep(i,0,n){
		cin >> a[i];
	}

	random_device seed_gen;
	mt19937 engine(seed_gen());
	uniform_int_distribution<ll> dist(0, (1LL<<62)-1);

	vector<ll> ac = compress(a);
	map<ll,ll> mp1;
	map<ll,ll> mp2;
	rep(i,0,(int)ac.size()){
		mp1[ac[i]] = dist(engine);
		mp2[ac[i]] = dist(engine);
	}
	
	ll t1 = 0, t2 = 0;

	vector<ll> ans;
	int pl = 0;
	int pr = n-1;
	rep(i,0,n){
		t1 += mp1[a[pl]];
		t1 -= mp1[a[pr]];
		t2 += mp2[a[pl]];
		t2 -= mp2[a[pr]];
		pl++;
		pr--;
		if (t1 == t2 && t1 == 0) ans.push_back(i+1);
	}
	rep(i,0,(int)ans.size()){
		cout << ans[i];
		if (i == (int)ans.size() - 1) cout << '\n';
		else cout << ' ';
	}
}
accuracy: 1
time_ms: 110
memory_kb: 11028
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ld=long double;
using vll=vector<ll>;
using pll=pair<ll,ll>;
using mpll=map<ll,ll>;
using vvll=vector<vector<ll>>;
using vpll=vector<pair<ll,ll>>;
using vstr=vector<string>;
using Graph=vvll;
const ll INF=0x1fffffffffffffff;
const ll MOD=998244353;
const ll MODD=1000000007;
const ld PI=3.1415926535897932;
#define overload4(_1,_2,_3,_4,name,...) name
#define rep1(a) for(ll i=0;i<a;i++)
#define rep2(i,a) for(ll i=0;i<a;i++)
#define rep3(i,a,b) for(ll i=a;i<b;i++)
#define rep4(i,a,b,c) for(ll i=a;i<b;i+=c)
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(n) for(ll i=(n)-1;i>=0;i--)
#define rrep2(i,n) for(ll i=(n)-1;i>=0;i--)
#define rrep3(i,a,b) for(ll i=(b)-1;i>=(a);i--)
#define rrep4(i,a,b,c) for(ll i=a+(b-a-1)/c*c;i>=a;i-=c)
#define rrep(...) overload4(__VA_ARGS__,rrep4,rrep3,rrep2,rrep1)(__VA_ARGS__)
#define each(i,a) for(auto &i:a)
#define all(i) begin(i),end(i)
#define rall(i) rbegin(i),rend(i)
#define vec(type,name,...) vector<type>name(__VA_ARGS__)
#define vv(type,name,h,...) vector name(h,vector<type>(__VA_ARGS__))
template<class T>bool chmin(T&a,const T&b){if(a>b){a=b;return 1;}return 0;}
template<class T>bool chmax(T&a,const T&b){if(a<b){a=b;return 1;}return 0;}
template<class T>auto min(const T&a){return*min_element(all(a));}
template<class T>auto max(const T&a){return*max_element(all(a));}
template<class T>ll sum(const T&a){return accumulate(all(a),0LL);}

int main(){
  ll n;
  cin>>n;
  vll a(n);
  rep(n)cin>>a[i];
  vll r=a;
  reverse(all(r));
  mpll mp;
  set<ll> s;
  bool f=0;
  rep(n){
    if(s.find(a[i])!=s.end()){
      mp[a[i]]++;
      if(mp[a[i]]==0)s.erase(a[i]);
    }
    else{
      mp[a[i]]++;
      s.emplace(a[i]);
    }

    if(s.find(r[i])!=s.end()){
      mp[r[i]]--;
      if(mp[r[i]]==0)s.erase(r[i]);
    }
    else{
      mp[r[i]]--;
      s.emplace(r[i]);
    }
    
    if(s.empty()){
      if(f)cout<<" ";
      cout<<i+1;
      f=1;
    }
  }
  cout<<endl;
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 8784
final_rank: 18

code_snippet: //#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
//using uLL = unsigned __int128;
using str = string;
template <typename T> 
using pqg = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using pq = priority_queue<T>;
template <typename T>
using vec = vector<T>;
using pll = pair<long long, long long>;
using pii = pair<int, int>;
using vvvvl = vector<vector<vector<vector<ll>>>>;
using vvvi = vector<vector<vector<int>>>;
using vvvl = vector<vector<vector<ll>>>;
using vvvc = vector<vector<vector<char>>>;
using vvvd = vector<vector<vector<double>>>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<ll>>;
using vvc = vector<vector<char>>;
using vvp = vector<vector<pair<ll, ll>>>;
using vvb = vector<vector<bool>>;
using vvd = vector<vector<double>>;
using vp = vector<pair<ll, ll>>;
using vi = vector<int>;
using vl = vector<ll>;
using vu = vector<unsigned long long>;
using vc = vector<char>;
using vb = vector<bool>;
using vd = vector<double>;
#define vvvm  vector<vector<vector<mint>>>
#define vvm  vector<vector<mint>>
#define vm  vector<mint>
template <typename T1, typename T2>
using umap = unordered_map<T1, T2>;
template <typename T>
using uset = unordered_set<T>;
#define rep(i, s, f) for(long long i = s; i <= f; i++)
#define rep1(i, s, f) for(long long i = s; i <= f; i++)
#define per(i, s, f) for(long long i = s; i >= f; i--)
#define per1(i, s, f) for(long long i = s; i >= f; i--)
#define eb(a) emplace_back(a)
#define pb(a) push_back(a)
#define all0(x) (x).begin() ,(x).end()
#define all(x) (x).begin() + 1, (x).end()
#define ins(x, l, r) (l <= x && x <= r)
#define ENDL '\n'
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//これが本当の組み込み関数ってね（笑）
template <typename T>
int LB(vector<T> &A, T x) {
    return lower_bound(A.begin(), A.end(), x) - A.begin();
}

template <typename T>
int UB(vector<T> &A, T x) {
    return upper_bound(A.begin(), A.end(), x) - A.begin();
}
template <typename T>
void UNIQUE(vector<T> &A, int indexed) {
    sort(A.begin() + indexed, A.end());
    A.erase(unique(A.begin() + indexed, A.end()), A.end());
}

template <typename T>
vector<T> erase(vector<T>& A, T& x) {
	vector<T> res;
	for(T a : A) if(a != x) res.emplace_back(a);
	return res;
}
string split(string& S, int l, int r) {
	return S.substr(l, r - l + 1);
}

int msb(long long a) {
    if(a == 0) return -1;
    return 64 - int(__builtin_clzll(a));
}
template<typename T = long long>
void chmin(T &a, T b) {
    a = min(a, b);
}
template<typename T = long long>
void chmax(T &a, T b) {
    a = max(a, b);
}
//////////////////////////////////////////////////////////////////////
//数学系
///////////////////////////////////////////////////////////////////////
ll extgcd (ll a, ll b,  ll &x, ll &y) {
    if(b == 0) { x = 1;y = 0;return a;}
    ll d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
template <typename T>
T ceil__(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b + 1;
    else return a / b;
}
template <typename T>
T floor__(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b;
    else return a/b - 1;
}
ll modpow(ll x, ll y, ll mod) {
    if(x > mod) x %= mod;
    if(y == 0) return 1;
    ll res = modpow(x, y >> 1, mod);
    res = res * res % mod;
    if(y & 1) res *= x, res %= mod;
    return res;
}
ll sqrt__(ll a) {
    ll l = 0;
    ll r = 3037000499LL;
    while(l < r) {
        ll mid = (l + r + 1) / 2;
        if(mid * mid <= a) l = mid;
        else r = mid - 1;
    }
    return l;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//グローバル変数を置くところ
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize "trapv" //お祈り。変数同士の演算でのみ感知。代入や、 a *= 10000 では感知しない。
const ll big = 1001001001;
const ll BIG = 1001001001001001001LL;
const double pi = 3.141592653589793;
vl dx{0, 1, 0, -1, 0, 1, 1, -1, -1};  // 座標平面において、(番兵) → ↓ ← ↑  ※ 右から時計回り 注 : グリッド or 座標で上下は反転する。
vl dy{0, 0, -1, 0, 1, 1, -1, -1, 1};
//const ll mod = 1000000007;
//const ll mod = 998244353;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



void solve() {
	ll N;
	cin >> N;
	vl A(N+1);
	rep(i,1,N) cin >> A[i];


	set<ll> nor;
	map<ll, int> L;
	map<ll, int> R;
	
	vi ans;

	rep(r, 1, N) {
		L[A[r]]++;
		R[A[N-r+1]]++;
		nor.erase(A[r]);
		nor.erase(A[N-r+1]);

		if(L[A[r]] != R[A[r]]) nor.insert(A[r]);
		if(L[A[N-r+1]] != R[A[N-r+1]]) nor.insert(A[N-r+1]);

		if(nor.empty()) ans.push_back(r);
	}

	ll M = ans.size();
	rep(i, 0, M-2) cout << ans[i] << " ";
	if(M >= 1) cout << ans[M-1] << endl;
	return;
	
    

    
    

}



int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);
    ll T = 1;
    //cin >> T;
    rep(i, 1, T) {
        solve();
    }
    return 0;
}



/*

- WA : 違法な読み替えをしていないか・違法な操作をしていないか
・実装が重そうな時は確認する 一度飛ばしても良い
・嘘を吐いていないかの他に、違法な操作をしていないかもチェックする。特にふわっとした操作は危ない
  -区間をちょっと伸ばす←端の時、伸ばす余地はあるか
  -選択肢のうち、どれでも良いから消す←本当にどれでも良いか 場合分けを挟んでないか そもそも消せる要素は存在するか
  -適当に割り振る←順番を区別する必要があるかもしれない
・答えの候補にはならないからと言って最初から無かったことにすると、その要素による制約も無視してしまう事がある。
・dpで途中までは辻褄が合っても、最後に分岐するので纏めてはいけない遷移というのがある



[整理パート] とりあえずやること
・必ずやらなければいけない操作は、順番が許すなら最初にやる
・確実にかかる費用があるなら、その費用は確定した上で他にかかる費用を最小化する。
・要素と制約をグラフで表してみる
  -関係がある要素間を辺で結び、制約上独立な要素集合ごとに見る
    ・二部グラフ > functional graph 出次数1なら functional graphの方が見えやすいかも
  -遷移を図で表現し、使いまわしたりできないか見る
  -グラフの2頂点に注目するなら、その2頂点を引っ張る or 2頂点のlcaに注目する。
・制約を「全ての要素についてoo ⇔ (1<=i<=N)で、iについてoo」といったように、独立なものに言い換えた方がやりやすいこともある
  -特に、bit演算が絡む時は、整数をbit毎に見る事で1つの制約を扱いやすい制約30個に分解できる(bit演算以外の時は、この30個が複雑に絡み合う可能性が高くなる)

・スコア・問題を数式で表現する。多少複雑そうでも、試みるぐらいはする。
  -複雑そうだし、役に立たないのでは？という直感はゴミ
  
・操作を制約に合わせて言い換える・制約を操作に合わせて言い換える。言い換えない方が良いことは多々ある。
  -全てがの要素が等しい⇔差分列が全て0
  -階差数列⇔差分列の要素の値が等しい
  -配列の、まとまった領域に対するよく分からない操作は(1)何ができるか調べる(2)何が作れるのか調べる(3)差分列に注目(4)modMごとに分けてみる(5)累積和列に注目

・よくわからないもの・扱いづらいものを言い換える。
  -特に、慣れ親しんだ制約も、問題設定によってより扱いやすい形に言い換えられるかもしれない（例：グラフが連結)
・強い制約は、数え上げ・最適化・クエリ・ゲーム共に良い性質を生みやすいので注目する
  -制約に具体的な数値が登場している←適当に解をいじると何となく性質が見えることが多い
  -強い言葉を使われた・補集合が単純なものを提示されたら、ほう助を疑う。 
     -「値がxに一致しない」
     -「1つ以上存在する・1つも存在しない」
     -「1回以上発生する・1度も発生しない」
     

[観察]  様々な解法も、実際試さないとそれで解けると分からないことは多い。
[]それらしい筋を書いておく → 一本道でもない限り、それぞれの解法をある程度並行して考える。 また、困ったら全部の筋を試す。
  -特に、最初に建てた方針は等しく皆大事にする。1つにのめり込むことのない様に。
[]１5分毎ぐらいに進捗を確認する←考察が進んでいない・闇雲な無限整理編に入っていたら、その筋はやばい可能性が高いので他の筋があれば変える。あるいは飛ばす。
	-数学的な式を満たす値は、グラフを書いたり列挙をすることで性質が見えることもある。
  -数学的な求値は、意味づけによる計算量削減が難しいが、漸化式的な発想が役に立つことが多い。
    ・combinationが入るΣ
	-満たすものが少なそうな制約は、同時に探索空間も小さくできるかも
  -問題設定によって、探索空間そのものが狭くなっている場合がある。


[やる事ない]
・取れる選択肢がある限り全て試す。一つに固執せず、横断的に見る。
・過去の問題の手法を当てはめてみる。
・やばい見た目してても、スコアなどを数式で表すことを試みてみる
  -貪欲や何かが見えるかも
・逆に、何ができる・成り立っているなら問題を解けるかを考える。それが実際できることを疑う。
  -大胆予想が正しい
    ・大胆予想：特殊ケース（c=0等)の時の答えと、一般のケースの答えが一致する
    ・大胆予想：必要十分条件がooである


[やる事ない：数え上げ周り] どれかに当てはまれば、解ける。そして、だいたいどれか。
[0]状態を保ちながら、順々に探索していける [1]探索空間そのものに特徴がある [2]解に特徴がある [3]探索順を変える [4]全探索の対象を全て試す [5]主客逆転 [6]昔計算した結果を再利用できる
  -[0]持つべき情報...「その状態から後にどの様に分岐すか」を求めるのに必要な情報 
  -[3]でかい方から、深い方から、DAGで先端になっている・或いは葉になっている所から、全てを逆に言い換えて時系列的に後ろから ... で、構造が単純になることがある。
    -特に,左から決定していく探索について:「要素ごとに寄与が分解できない」という時も、新たに要素が増えることによる"全体の寄与の変化"が高速に計算できれば解ける。主客転倒と近いかもしれない。
  -[4]固定するものの数が多くても、何かを固定した時の場合の和が綺麗に表せれば、固定するものを纏めて計算できる。
  -[5]演算が+やxorなどの分解して良いやつの時


[やる事ない：最適化周り]
[0]順番を保ちながら、順々に探索していける [1]探索空間そのものに特徴がある [2]解の形を絞れる [3]答えを決め打って判定問題 [4]最悪ケース・最良ケースを纏めると、スコアに関わる本質部分がわかって、場合分けが進む/上界・下界が絞れる。 
[5]条件を満たす為の操作・構築として、具体的な操作考を考え、改善していく [6]探索順を変える [7]探索の軸を変える [8]特殊ケースの解方が一般ケースでも最適 [9]自由度を無視しても最適解が構築できる
  -[0]特に、操作が順番に寄らない時は選択肢としてあり得る。順番に寄る時は難しいかもしれない。
  -[0]条件を満たしながら最適化という時、条件が簡潔・存在しないならばそれに至るまでにありうる状態を全て状態として持つdpが可能かもしれない。
    -例:連続とは限らない部分文字列としてabcを含まない/含む様にする時の最小操作回数
  -[3]答えに限らず、何かが定まれば貪欲がありそうという時に有効（目標とする値・何かの上限...)
  -[4]最悪・最良の疑いがある解を見つけたら、最悪である必要条件を考えて、最悪ケースを特徴づけする。その後、２番目に最悪ケースについて同じことをしたり、他のケースに含まれる部分的な最悪ケースが支配的になっていることを考える。
  -[5]ooを満たす為の「最小の操作回数」や「コストがC以下の操作」を聞かれた際、「ooを満たす様な具体的な操作・構築」を考える事になる。
    -初期状態が満たす可能性があるなら、それを省く。条件が"ooでない"、の時、初期状態がooであるという制約がつく等嬉しい。
    -同じ条件を満たす様な操作・構築の中では、自由度がより高いのが良い。
    -後から調整可能なのは後回し。支配的なのは出来るだけ最初に。
    -やってはいけない事を禁止。何ができるか。
    -最小化等を考えずに、ともかく与えられた操作・制約・上限コストでどの様な解が作れるか。([1])
    -この構築で可能か？を探る際は、最悪ケースで実験する。穴がある解を未然に防ぐ。
    -それっぽい操作を考えたが、できない事がある→できる場合・できない場合を特徴づける。
      -出来ない条件を探る過程で、本質的な必要十分に辿り着くかもしれない。 例：木の深さの偶奇が関わる→二部グラフにした時... , 二部グラフにできない時...
      -より条件を絞った状態で考えられる。
  -[6]でかい方から、深い方から、DAGで先端になっている・或いは葉になっている所から、全てを逆に言い換えて時系列的に後ろから ... で、貪欲が見えたり構造が単純になることがある。
  -[7]今給油するか？では無く、「ここで必要なガソリンはどこで給油するか？
・「最適な操作順」や「操作順に関する貪欲」なんてわからないという時、一旦引いて「ooの分のコストは確実にかかる」等を整理すると、手順を陽に明かさずとも最適な答えがわかることはある。
・bit演算がメインなら、bitごとにみる。特に、msbに注目する。（数が少ないので必要条件になりやすい・大きくする時の貪欲はとにかく上を立てる)
・関係をグラフに起こしてあると気づきやすいこともある
・スコアを数学的な式で表すことを試みたか
・差分を計算するなら、最初から差分計算の処理のみで答えを計算した方が良い。最初を愚直でやると情報をロストする可能性があるし、愚直の枠組みに囚われる事もある。
・文字列周りのアルゴリズムは、昔の結果を利用して高速に計算する方法を述べているのであって、「回文がminになるoo」を求めるのには役に立たない？

[やる事ない：クエリ]
[1]1回のクエリが高速に計算できる  [2]最終的に求める値がそれぞれ高速に計算できる [3]差分が計算できる [4]最終的に求める値が並列に計算できる 
  -[1]確かに1回のクエリが解けた事を確認してから更新を考える事  解ける前から「直観的に必要そうな情報」の更新を考えたりしない (制約を元に、計算量をメタ読みするのは良い)

[やる事ない：操作列の長いシュミレーション周り]
[1]周期性がある  [2]結果を基準に見る, [3]再帰的に計算できる [4]時間のかかる操作の回数が少ない
  -[2]...操作を順々にしていくのでは無く、求めるものを直接求めにいく
   -「(削除の)シュミレーションを高速にやる」と「要素が最後まで残る必要条件をみる」
  -[1],[3] 綺麗な構造になっていれば
  -[4]...シュミレーションを実行するのに必要な計算を列挙する。重いやつのうち、実際にやらなければならない回数が実は少ないなど。



[高速化ネタ]
・lcmを含む式はgcdの式にする
・操作のどれを1段階とするかは自由に決めて良い(DPと同じ)。特に、操作をさらに細かくすることで1回を軽くすることもある。
・dpやシュミレーションで、段階によって遷移(計算)の本数が変化する時、貰う・配るを両立することでO(N√N)  注意：貰っても配っても良い時のみ。具体的に、期待値ではダメ。
・「全探索する軸が違うのに計算量同じな解法のペアがある」 と 「それぞれに得意・貪欲によりさらに計算量を減らせる範囲だけを計算させることでO(N√N)
 -自由度が2つ以上あるときなど 例：「数列が等差数列である ... 「一つ、数列の値を指定する」と「公差を指定する」
・「明らかに調べなくて良い」「これだけは別途楽に計算できる」事を事前に省いた結果、実は計算量を劇的に減らすことがある。主に最適化の文脈。
  -最悪ケースを考えると気づくかもしれない
・答えの個数・値が小さいなら、探索範囲をせばせて良いかも
・「bit/素因数ごとに分ける」と「分けずにまとめて計算する」

*/
accuracy: 1
time_ms: 120
memory_kb: 10996
final_rank: 20

code_snippet: #include <bits/stdc++.h>
// #include <atcoder/all>
// using namespace atcoder;
using namespace std;
typedef long long ll;
typedef long double ld; 
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
// using mint = modint998244353;
// using mint = modint1000000007;
ll mod = 998244353;
// ll mod = 1000000007;
ll inf = 2e18;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(a) (a).begin(), (a).end()
template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
multiset<ll> s,t;
void solve(){
    ll n;
    cin>>n;
    vector<ll> a(n);
    rep(i,n){
        cin>>a[i];
    }
    // return;
    rep(i,n){
        if(t.find(a[i]) == t.end()){
            s.insert(a[i]);
        }
        else{
            t.erase(t.find(a[i]));
        }
        // cout <<"@" << endl;
        if(s.find(a[n-1-i]) == s.end()){
            t.insert(a[n-1-i]);
        }
        else{
            s.erase(s.find(a[n-1-i]));
        }
        if(s.empty()){
            if(i != n-1)cout << i+1 << " ";
            else cout << i+1;
        }
    }
    cout << endl;
}
int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr);
    solve();
}
accuracy: 1
time_ms: 40
memory_kb: 4796
final_rank: 2

code_snippet: // SPDX-License-Identifier: MIT
// (c) 2023 TwoSquirrels
// my AtCoder environment: https://github.com/TwoSquirrels/atcoder-env

//#define DEBUG

// enable debug mode when compiled with -DDEBUG
#ifdef DEBUG
#  define IS_DEBUG (1)
#else
// QCFium method
#  pragma GCC target("avx2")
#  pragma GCC optimize("O3")
#  pragma GCC optimize("unroll-loops")
#  pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
#  define IS_DEBUG (0)
#endif

/// includes

// standard libraries
#if __has_include(<bits/stdc++.h>)
#  include <bits/stdc++.h>
#else // <bits/stdc++.h>
// C++17 (clang)
#  include <cassert>
#  include <cfenv>
#  include <cfloat>
#  include <ciso646>
#  include <clocale>
#  include <csetjmp>
#  include <csignal>
#  include <cstdbool>
#  include <cinttypes>
#  include <charconv>
#  include <typeindex>
#  include <any>
#  include <scoped_allocator>
#  include <forward_list>
#  include <list>
#  include <map>
#  include <set>
#  include <valarray>
#  include <variant>
#  include <unordered_map>
#  include <unordered_set>
#  include <queue>
#  include <condition_variable>
#  include <shared_mutex>
#  include <codecvt>
#  include <future>
#  include <regex>
#  include <iostream>
#  include <random>
#  include <ctgmath>
#  include <fstream>
#endif // <bits/stdc++.h>

/// abi
#if __has_include(<cxxabi.h>)
#  define INCLUDED_CXXABI
#  include <cxxabi.h>
#endif // <cxxabi.h>

// boost libraries
#if __has_include(<boost/multiprecision/cpp_int.hpp>)
#  define INCLUDED_BOOST_CPP_INT
#  include <boost/multiprecision/cpp_int.hpp>
#endif
#if __has_include(<boost/math/special_functions/prime.hpp>)
#  define INCLUDED_BOOST_PRIME
#  include <boost/math/special_functions/prime.hpp>
#endif
#if __has_include(<boost/multiprecision/miller_rabin.hpp>)
#  define INCLUDED_BOOST_MILLER_RABIN
#  include <boost/multiprecision/miller_rabin.hpp>
#endif

// atcoder libraries
#if __has_include(<atcoder/all>)
#  define INCLUDED_ACL
#  include <atcoder/all>
#endif

/// sfinae

// is_pair
template <typename T> inline constexpr bool is_pair_v = false;
template <typename T, typename U> inline constexpr bool is_pair_v<std::pair<T, U>> = true;

// is_tuple
template <typename T> inline constexpr bool is_tuple_v = false;
template <typename... Types> inline constexpr bool is_tuple_v<std::tuple<Types...>> = true;

// istreamable
#if __cplusplus >= 202002L
template <typename T> concept istreamable_v = requires (T a) { std::cin >> a; };
#else // C++20
template<typename T, typename = void> inline constexpr bool istreamable_v = false;
template<typename T>
inline constexpr bool istreamable_v<T, std::void_t<decltype(std::cin >> std::declval<T&>())>> = true;
#endif // C++20

// ostreamable
#if __cplusplus >= 202002L
template <typename T> concept ostreamable_v = requires (T a) { std::cout << a; };
#else // C++20
template<typename T, typename = void> inline constexpr bool ostreamable_v = false;
template<typename T>
inline constexpr bool ostreamable_v<T, std::void_t<decltype(std::cout << std::declval<T&>())>> = true;
#endif // C++20

// iterable
#if __cplusplus >= 202002L
#  if __has_include(<ranges>)
template <typename T> concept iterable_v = std::ranges::range<T>;
#  else // <ranges>
template <typename T> concept iterable_v = requires (T a) { std::begin(a); std::end(a); };
#  endif // C++20
#else // C++20
template <typename T> inline constexpr bool iterable_v =
  std::is_same_v<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>;
#endif // C++20

/// utils

template <typename T> inline std::string get_typename(std::size_t length_limit = std::string::npos) {
  std::string name;
#ifdef INCLUDED_CXXABI
  name = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, nullptr);
#else // INCLUDED_CXXABI
  name = typeid(T).name();
#endif // INCLUDED_CXXABI
#ifdef __ANDROID__
  name = std::regex_replace(name, std::regex("::__ndk1::"), "::");
#endif // __ANDROID__
  if (name.length() > length_limit) name = name.substr(0, length_limit - 3) + "...";
  return name;
}

template <typename T> constexpr T inf() {
  if constexpr (std::numeric_limits<T>::has_infinity) return std::numeric_limits<T>::infinity();
  return std::numeric_limits<T>::max() / 2.125L;
}

template <typename T> constexpr int sin90(T theta90) {
  if (theta90 % 2 == 0) return 0;
  return (theta90 % 4 + 4) % 4 < 2 ? 1 : -1;
}
template <typename T> constexpr int cos90(T theta90) {
  return sin90(theta90 + 1);
}
template <typename T> constexpr int sin45(T theta45) {
  if (theta45 % 4 == 0) return 0;
  return (theta45 % 8 + 8) % 8 < 4 ? 1 : -1;
}
template <typename T> constexpr int cos45(T theta45) {
  return sin45(theta45 + 2);
}

template <typename T, typename U> inline bool chmin(T &&a, const U b) {
  const bool compare = a > b;
  if (compare) a = b;
  return compare;
}
template <typename T, typename U> inline bool chmax(T &&a, const U b) {
  const bool compare = a < b;
  if (compare) a = b;
  return compare;
}

long long powi(int base, int exponent = 2) {
  long long ans = 1;
  for (int i = exponent; i != 0; i += (i >= 0 ? -1 : 1)) {
    if (i >= 0) ans *= base;
    else ans /= base;
    if (ans == 0) break;
  }
  return ans;
}

#ifdef INCLUDED_ACL
template <typename T = atcoder::modint>
T mint_inv(T x) {
  constexpr int memo_limit = 1 << 24;
  static std::array<T, memo_limit> memo;
  if (x.val() >= memo_limit) return x.inv();
  if (memo[x.val()] == 0) memo[x.val()] = x.inv();
  return memo[x.val()];
}
#endif // INCLUDED_ACL

template <typename T> bool is_prime(T n) {
  if (n <= 1) return false;
  if (n == 2 || n == 3) return true;
  if (n % 2 == 0 || n % 3 == 0) return false;
  // miller rabin
#ifdef INCLUDED_ACL
  if (n <= std::min(1LL << 32, static_cast<long long>(std::numeric_limits<int>::max()))) {
    return atcoder::internal::is_prime_constexpr(n);
  }
#endif // INCLUDED_ACL
#ifdef INCLUDED_BOOST_MILLER_RABIN
  return boost::multiprecision::miller_rabin_test(n, 25);
#endif // INCLUDED_BOOST_MILLER_RABIN
  // binary search
#ifdef INCLUDED_BOOST_PRIME
  if (n <= boost::math::prime(boost::math::max_prime)) {
    int left = 0, right = boost::math::max_prime + 1;
    while (right - left > 1) {
      auto mid = (left + right) / 2;
      (boost::math::prime(mid) <= n ? left : right) = mid;
    }
    return n == boost::math::prime(left);
  }
#endif // INCLUDED_BOOST_PRIME
  // trial
  T tried = 3;
#ifdef INCLUDED_BOOST_PRIME
  for (int i = 2; i <= int(boost::math::max_prime); i++) {
    const auto prime_i = boost::math::prime(i);
    if (prime_i > n / prime_i) return true;
    if (n % prime_i == 0) return false;
    tried = prime_i;
  }
#endif // INCLUDED_BOOST_PRIME
  for (T i = (tried + 5) / 6 * 6; (i - 1) * (i - 1) <= n; i += 6) {
    if (n % (i - 1) == 0 || n % (i + 1) == 0) return false;
  }
  return true;
}

// thanks to https://perogram.hateblo.jp/entry/2019/03/29/193632
template <bool osa_k = false, typename T> std::vector<std::pair<T, int>> factors(T n) {
  constexpr int spf_limit = 1 << 24;
  std::vector<std::pair<T, int>> result;
  if (n < 0) {
    result.emplace_back(-1, 1);
    const auto natural = factors<osa_k>(-n);
    result.insert(result.end(), natural.begin(), natural.end());
  } else if (n == 0) result.emplace_back(0, 1);
  else if (n == 1);
  else if (osa_k && n < spf_limit) {
    static std::array<int, spf_limit> spf;
    if (spf[0] == 0) {
      for (int i = 0; i < spf_limit; i++) spf[i] = i % 2 == 0 ? 2 : i % 3 == 0 ? 3 : i;
      spf[0] = 1;
      for (int p1 = 6; (p1 - 1) * (p1 - 1) <= spf_limit; p1 += 6) {
        if (spf[p1 - 1] == p1 - 1) for (int i = p1 - 1; i < spf_limit; i += p1 - 1) if (spf[i] == i) spf[i] = p1 - 1;
        if (spf[p1 + 1] == p1 + 1) for (int i = p1 + 1; i < spf_limit; i += p1 + 1) if (spf[i] == i) spf[i] = p1 + 1;
      }
    }
    while (n != 1) {
      if (!result.empty() && result.back().first == spf[n]) result.back().second++;
      else result.emplace_back(spf[n], 1);
      n /= spf[n];
    }
  } else {
    int expo = 0;
    while (n % 2 == 0) { n /= 2; expo++; }
    if (expo != 0) result.emplace_back(2, expo);
    expo = 0;
    while (n % 3 == 0) { n /= 3; expo++; }
    if (expo != 0) result.emplace_back(3, expo);
    T tried = 3;
#ifdef INCLUDED_BOOST_PRIME
    for (int i = 2; i <= int(boost::math::max_prime); i++) {
      const auto prime_i = boost::math::prime(i);
      if (prime_i > n / prime_i) break;
      expo = 0;
      while (n % prime_i == 0) { n /= prime_i; expo++; }
      result.emplace_back(prime_i, expo);
      tried = prime_i;
    }
    if (osa_k && n < spf_limit) {
      const auto rest = factors<osa_k>(n);
      result.insert(result.end(), rest.begin(), rest.end());
      n = 1;
    }
#endif // INCLUDED_BOOST_PRIME
    if (is_prime(n)) { result.emplace_back(n, 1); n = 1; }
    for (T i = (tried + 5) / 6 * 6; (i - 1) * (i - 1) <= n; i += 6) {
      expo = 0;
      while (n % (i - 1) == 0) { n /= (i - 1); expo++; }
      if (expo != 0) result.emplace_back(i - 1, expo);
      expo = 0;
      while (n % (i + 1) == 0) { n /= (i + 1); expo++; }
      if (expo != 0) result.emplace_back(i + 1, expo);
      if (osa_k && n < spf_limit) {
        const auto rest = factors<osa_k>(n);
        result.insert(result.end(), rest.begin(), rest.end());
        n = 1;
      }
    }
    if (n != 1) result.emplace_back(n, 1);
  }
  return result;
}

template <bool osa_k = false, typename T> std::vector<T> divisors(T n) {
  std::vector<T> result(1, 1);
  for (auto [prime, expo] : factors<osa_k>(n)) {
    const int result_size = result.size();
    T pow_i = 1;
    for (int i = 1; i <= expo; i++) {
      pow_i *= prime;
      for (int k = 0; k < result_size; k++) result.emplace_back(result[k] * pow_i);
    }
  }
  std::sort(result.begin(), result.end());
  return result;
}

template <typename T> T fact(int n, bool inv = false) {
  assert(n >= 0);
  static std::vector<std::pair<T, T>> factorials = { { 1, 1 } };
  for (int i = factorials.size(); i <= n; i++) factorials.emplace_back(i * factorials[i - 1].first, 0);
  if (inv && factorials[n].second == 0) {
    if constexpr (std::is_integral_v<T>) factorials[n].second = factorials[n].first <= 1 ? 1 : 0;
#ifdef INCLUDED_ACL
    else if constexpr (atcoder::internal::is_modint<T>::value) factorials[n].second = mint_inv(factorials[n].first);
#endif // INCLUDED_ACL
    else factorials[n].second = 1 / factorials[n].first;
  }
  return inv ? factorials[n].second : factorials[n].first;
}
template <typename T> T perm(int n, int k) { return fact<T>(n) * fact<T>(n - k, true); }
template <typename T> T comb(int n, int k) { return perm<T>(n, k) * fact<T>(k, true); }

// TODO: compressor
/*template <typename T> struct compressor {
  std::vector<T> positions;
  compressor() = default;
  compressor(const std::vector<T> &initial_pos) {
    
  }
};*/

template <typename T> std::vector<std::vector<T>> rotate(std::vector<std::vector<T>> grid, int angle = 1) {
  angle %= 4;
  if (angle == 0) return grid;
  auto h = grid.size(), w = grid[0].size();
  auto rotated = std::vector(w, std::vector<T>(h));
  for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) rotated[w - 1 - x][y] = grid[y][x];
  return rotate(rotated, angle - 1);
}

std::string int128_to_str(__int128_t target) {
  std::string target_str;
  __uint128_t target_tmp = target < 0 ? -target : target;
  do {
    target_str += '0' + target_tmp % 10;
    target_tmp /= 10;
  } while (target_tmp != 0);
  if (target < 0) target_str += '-';
  std::reverse(target_str.begin(), target_str.end());
  return target_str;
}

template <typename T> std::string to_pretty_str(T target) {
  using namespace std;
  string str;
  if constexpr (is_void_v<T>) str += "void"s;
  else if constexpr (is_null_pointer_v<T>) str += "null"s;
  else if constexpr (is_same_v<T, bool>) str += target ? "true"s : "false"s;
  else if constexpr (is_same_v<T, char> || is_same_v<T, char16_t> || is_same_v<T, char32_t> || is_same_v<T, wchar_t>) {
    str += "'"s + target + "'"s;
#ifdef INCLUDED_ACL
    } else if constexpr (atcoder::internal::is_modint<T>::value) {
    str += to_string(target.val()) + "(mod)"s;
#endif // INCLUDED_ACL
  } else if constexpr (is_arithmetic_v<T>) {
    if constexpr (is_same_v<T, __int128_t>) str += int128_to_str(target);
    else str += to_string(target);
    if constexpr (is_unsigned_v<T>) str += "u"s;
    if constexpr (is_same_v<remove_cv_t<T>, long>) str += "L"s;
    else if constexpr (is_same_v<remove_cv_t<T>, long long>) str += "LL"s;
    else if constexpr (is_same_v<T, __int128_t>) str += "LLL"s;
  } else if constexpr (is_pair_v<T>) {
    str += "("s + to_pretty_str(target.first);
    str += ", "s + to_pretty_str(target.second) + ")"s;
  } else if constexpr (is_convertible_v<T, string>) {
    str += "\""s + target + "\""s;
  } else if constexpr (is_array_v<T>) {
    str += "["s;
    bool separate = false;
    for (const auto &target_i : target) {
      if (separate) str += ", "s;
      str += to_pretty_str(target_i);
      separate = true;
    }
    str += "]"s;
  } else if constexpr (iterable_v<T>) {
    str += get_typename<T>(20) + "{"s;
    bool separate = false;
    for (const auto &target_i : target) {
      if (separate) str += ","s;
      str += " "s + to_pretty_str(target_i);
      separate = true;
    }
    if (separate) str += " "s;
    str += "}"s;
  } else {
    str += "<"s + get_typename<T>(20);
    str += " ("s + to_string(sizeof(target)) + " byte)>"s;
  }
  return str;
}

// input
#ifdef DEBUG
std::chrono::milliseconds input_total_ms{0};
#endif // DEBUG
template <typename T> inline void read_stdin(T &&target) {
#ifdef DEBUG
  using namespace std::chrono;
  const auto start = system_clock::now();
  std::cin >> target;
  const auto end = system_clock::now();
  input_total_ms += duration_cast<milliseconds>(end - start);
#else // DEBUG
  std::cin >> target;
#endif // DEBUG
}
template <typename T> inline T input(T &&target) {
  using T_V = std::remove_reference_t<T>;
  if constexpr (istreamable_v<T_V>) read_stdin(target);
  else if constexpr (iterable_v<T_V>) for (auto &&target_i : target) input(target_i);
  else if constexpr (is_pair_v<T_V>) {
    input(target.first);
    input(target.second);
  } else if constexpr (std::is_convertible_v<long long, T_V>) {
    long long n;
    target = input(n);
  } else {
#ifdef DEBUG
    std::cerr << "[WARN] Type " << get_typename<T_V>()
              << " is invalid, so input is skipped;" << std::endl;
#endif //DEBUG
  }
  return target;
}
// input and initialize
struct Scanner { template <typename T> inline operator T() const { T target; return input(target); } } scan;

// output
template <typename T> inline void write_stdout(T target, bool flush = false) {
  std::cout << target;
  if (flush) std::cout << std::flush;
}
template <typename T, typename Sep = char> inline void output(T target, Sep separator = ' ', bool flush = false) {
  if constexpr (ostreamable_v<T>) {
    write_stdout(target, flush);
  } else if constexpr (std::is_convertible<T, __int128_t>::value) {
    write_stdout(int128_to_str(target), flush);
#  ifdef INCLUDED_ACL
    } else if constexpr (atcoder::internal::is_modint<T>::value) {
    output(target.val(), separator, flush);
#  endif // INCLUDED_ACL
  } else if constexpr (iterable_v<T>) {
    bool separate = false;
    for (const auto target_i : target) {
      if (separate) write_stdout(separator);
      output(target_i, separator);
      separate = true;
    }
    if (flush) write_stdout("", flush);
  } else if constexpr (is_pair_v<T>) {
    output(target.first, separator);
    write_stdout(separator);
    output(target.second, separator, flush);
  } else {
    write_stdout("<unknown>", flush);
  }
}
template <typename T, typename Sep = char> inline void outputln(T target, Sep separator = ' ', bool flush = false) {
  output(target, separator);
  write_stdout('\n', flush);
}

// debug output
#ifdef DEBUG
std::chrono::milliseconds debug_total_ms{0};
template <typename F> void debug_txt_f(F callback, int line = -1, std::string file = (__FILE__)) {
  using namespace std::chrono;
  const auto start = system_clock::now();
  std::string dump_str = "[DEBUG] ";
  if (line >= 0) {
    dump_str += "(";
    if (file != (__FILE__)) dump_str += file + ":";
    dump_str += "L" + std::to_string(line) + ") ";
  }
  dump_str += callback();
  std::cerr << dump_str << std::endl;
  const auto end = system_clock::now();
  debug_total_ms += duration_cast<milliseconds>(end - start);
}
#  define debug_txt(txt) (debug_txt_f([]() { return to_pretty_str(txt); }, (__LINE__), (__FILE__)), true)
template <typename... Types>
void dump_f(std::string labels, std::tuple<Types...> targets_tupl, int line = -1, std::string file = (__FILE__)) {
  debug_txt_f([=]() {
    std::string txt;
    std::apply([labels, &txt](auto... targets) {
      int i = 0, label_left = 0;
      (([&](auto target) {
        const auto label_len = labels.find(',', label_left) - label_left;
        const auto label =
          std::regex_replace(labels.substr(label_left, label_len),
                             std::regex("^\\s+|\\s+$"), "");
        if (i >= 1) txt += ", ";
        txt += label + ": " + to_pretty_str(target);
        label_left += label_len + 1;
        i++;
      })(targets), ...);
      txt += ";";
    }, targets_tupl);
    return txt;
  }, line, file);
}
#  define dump(...) (dump_f((#__VA_ARGS__), std::make_tuple(__VA_ARGS__), (__LINE__), (__FILE__)), true)
void dump_canvas_f(std::string label, std::vector<std::string> canvas, int line = -1, std::string file = (__FILE__)) {
  debug_txt_f([=]() {
    int h = canvas.size(), w = canvas[0].size();
    std::string txt = label + " (" + std::to_string(h) + " x " + std::to_string(w) + ")\n";
    std::string ruler0(w, ' '), ruler1(w, '-');
    for (int x = 0; x < w; x += 4) {
      auto x_s = std::to_string(x);
      for (std::size_t i = 0; i < x_s.size(); i++) ruler0[x - i] = x_s[x_s.size() - i - 1];
      ruler1[x] = '+';
    }
    txt += "   |" + ruler0 + "\n---+" + ruler1;
    for (int y = 0; y < h; y++) {
      std::string ruler = "   |";
      if (y % 4 == 0) {
        auto y_s = std::to_string(y);
        for (std::size_t i = 0; i < y_s.size(); i++) ruler[2 - i] = y_s[y_s.size() - i - 1];
        ruler[3] = '+';
      }
      txt += "\n" + ruler + canvas[y];
    }
    return txt;
  }, line, file);
}
#  define dump_canvas(canvas) (dump_canvas_f((#canvas), (canvas), (__LINE__), (__FILE__)), true)
// TODO: dump_table
#else // DEBUG
#  pragma GCC diagnostic push
#    pragma GCC diagnostic ignored "-Wunused-value"
#    define debug_txt(...) (false)
#    define dump(...) (false)
#    define dump_canvas(...) (false)
#  pragma GCC diagnostic pop
#endif // DEBUG

/// main

#if !defined(__INCLUDE_LEVEL__) || __INCLUDE_LEVEL__ <= 1

inline std::string cp_main();

int main() {
  using namespace std;
  using namespace std::chrono;
#  ifdef DEBUG
  cerr << "[INFO] running in debug mode!" << endl;
  const auto start = system_clock::now();
  try {
#  endif // DEBUG
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(8);
    // run!!!
    const auto result = cp_main();
    if (!result.empty()) write_stdout(result);
#  ifdef DEBUG
    write_stdout('\n', true);
  } catch (exception &e) {
    write_stdout('\n', true);
    cerr << "[ERROR] " << e.what() << endl;
  }
  const auto end = system_clock::now();
  const auto time_ms = duration_cast<milliseconds>(end - start) - input_total_ms - debug_total_ms;
  cerr << "[INFO] finished in " << time_ms.count() << " ms!" << endl;
#  endif // DEBUG
  return 0;
}

#endif // __INCLUDE_LEVEL__

/// aliases

using i32 = int; using u32 = unsigned int;
using i64 = long long; using u64 = unsigned long long;
using i128 = __int128; using u128 = unsigned __int128;
using f32 = float; using f64 = double; using f128 = long double;
using str = std::string;
template <typename T> using vec = std::vector<T>;
template <typename T, typename Compare = std::less<T>> using p_que = std::priority_queue<T, std::vector<T>, Compare>;
template <typename Key, typename Compare = std::less<Key>> using mset = std::multiset<Key, Compare>;
template <typename Key, typename T, typename Compare = std::less<Key>> using mmap = std::multimap<Key, T, Compare>;
template <typename Key> using u_set = std::unordered_set<Key>;
template <typename Key> using u_mset = std::unordered_multiset<Key>;
template <typename Key, typename T> using u_map = std::unordered_map<Key, T>;
template <typename Key, typename T> using u_mmap = std::unordered_multimap<Key, T>;
#ifdef INCLUDED_BOOST_CPP_INT
using bigint = boost::multiprecision::cpp_int;
#endif // INCLUDED_BOOST_CPP_INT

using namespace std;
#if __cplusplus >= 202002L && __has_include(<ranges>)
namespace rng = std::ranges;
namespace viw = std::ranges::views;
#endif // C++20 && <ranges>
#ifdef INCLUDED_ACL
using namespace atcoder;
#endif // INCLUDED_ACL

#pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wunused-variable"
constexpr auto infi = inf<int>();
constexpr auto infl = inf<long long>();
constexpr auto infd = inf<double>();
constexpr auto infld = inf<long double>();
const std::array YN = { "No"s, "Yes"s };
const std::array AB = { "Bob"s, "Alice"s };
const std::array FS = { "Second"s, "First"s };
const std::array TA = { "Aoki"s, "Takahashi"s };
#pragma GCC diagnostic pop

// functions
#define tostr to_string
#define dist distance
#define min_e min_element
#define max_e max_element
#define iota_v iota_view
#define p1 first
#define p2 second
#define has contains
#define eb emplace_back
#define ef emplace_front
#define pb pop_back
#define pf pop_front
// repeat
#define reps(i, l, r) for (std::decay_t<decltype(r)> i##_right = (r), i = (l); i < i##_right; i++)
#define rep(i, n) reps(i, 0, n)
#define rreps(i, l, r) for (std::decay_t<decltype(r)> i##_left = (l), i = (r) - 1; i >= i##_left; i--)
#define rrep(i, n) rreps(i, 0, n)
#define each(for_able) for (auto &&for_able##_i : (for_able))
// iterate
#define all(for_able) (std::begin(for_able)), (std::end(for_able))
#define rev(for_able) (std::rbegin(for_able)), (std::rend(for_able))
// lambda
#define pred(x, expr) ([&](auto &&x) -> bool { return (expr); })
#define comp(x, y, expr) ([&](auto &&x, auto &&y) -> bool { return (expr); })

/// answer

//using mint=modint998244353;

inline str cp_main() {
  int n=scan;
  auto a=input(vec<i64>(n));
  map<i64,int> yobun_l,yobun_r;
  vec<int> ans;
  reps(k,1,n+1){
    i64 l=a[k-1],r=a[n-k];
    if(l!=r){
      if(yobun_r[l]==0)yobun_l[l]++;
      else yobun_r[l]--;
      if(yobun_r[l]==0)yobun_r.erase(l);
      if(yobun_l[r]==0)yobun_r[r]++;
      else yobun_l[r]--;
      if(yobun_l[r]==0)yobun_l.erase(r);
    }
    if(yobun_l.empty()&&yobun_r.empty())ans.eb(k);
    dump(k,l,r,yobun_l,yobun_r);
  }
  outputln(ans);
  return "";
}
accuracy: 1
time_ms: 70
memory_kb: 5052
final_rank: 8

code_snippet: // author: hotman78
// date: 2024/04/12-18:04:42

// --- begin raw code -----------------
// #include"cpplib/util/template.hpp"
// 
// void solve(){
//     lint n;
//     cin>>n;
//     vec a(n);
//     rep(i,n)cin>>a[i];
//     map<lint,lint>m;
//     vec ans;
//     rep(i,n){
//         m[a[i]]++;
//         if(m[a[i]]==0){
//             m.erase(a[i]);
//         }
//         m[a[n-1-i]]--;
//         if(m[a[n-1-i]]==0){
//             m.erase(a[n-1-i]);
//         }
//         if(m.empty())ans.emplace_back(i+1);
//     }
//     output(ans);
// }
// 
// int main(){
//     solve();
// }
// --- end raw code -----------------

#line 2 "cpplib/util/template.hpp"
#ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")
#include <bits/stdc++.h>
using namespace std;
#line 1 "cpplib/util/ioutil.hpp"
// template <class Head,class... Args>
// std::ostream& output(std::ostream& out,const Head& head,const Args&... args){
//     out>>head;
//     return output(head,args...);
// }
// template <class Head>
// std::ostream& output(std::ostream& out,const Head& head){
//     out>>head;
//     return out;
// }

template <typename T, typename E>
std::ostream &operator<<(std::ostream &out, std::pair<T, E> v) {
    out << "(" << v.first << "," << v.second << ")";
    return out;
}

// template <class... Args>
// ostream& operator<<(ostream& out,std::tuple<Args...>v){
//     std::apply(output,v);
//     return out;
// }
#line 11 "cpplib/util/template.hpp"
struct __INIT__ {
    __INIT__() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
    }
} __INIT__;
typedef long long lint;
constexpr long long INF = 1LL << 60;
constexpr int IINF = 1 << 30;
constexpr double EPS = 1e-10;
#ifndef REACTIVE
#define endl '\n';
#endif
typedef vector<lint> vec;
typedef vector<vector<lint>> mat;
typedef vector<vector<vector<lint>>> mat3;
typedef vector<string> svec;
typedef vector<vector<string>> smat;
template <typename T> using V = vector<T>;
template <typename T> using VV = V<V<T>>;
#define output(t)                                                              \
    {                                                                          \
        bool f = 0;                                                            \
        for (auto val : (t)) {                                                 \
            cout << (f ? " " : "") << val;                                     \
            f = 1;                                                             \
        }                                                                      \
        cout << endl;                                                          \
    }
#define output2(t)                                                             \
    {                                                                          \
        for (auto i : t)                                                       \
            output(i);                                                         \
    }
#define debug(t)                                                               \
    {                                                                          \
        bool f = 0;                                                            \
        for (auto i : t) {                                                     \
            cerr << (f ? " " : "") << i;                                       \
            f = 1;                                                             \
        }                                                                      \
        cerr << endl;                                                          \
    }
#define debug2(t)                                                              \
    {                                                                          \
        for (auto i : t)                                                       \
            debug(i);                                                          \
    }
#define loop(n) for (long long _ = 0; _ < (long long)(n); ++_)
#define _overload4(_1, _2, _3, _4, name, ...) name
#define __rep(i, a) repi(i, 0, a, 1)
#define _rep(i, a, b) repi(i, a, b, 1)
#define repi(i, a, b, c)                                                       \
    for (long long i = (long long)(a); i < (long long)(b); i += c)
#define rep(...) _overload4(__VA_ARGS__, repi, _rep, __rep)(__VA_ARGS__)
#define _overload3_rev(_1, _2, _3, name, ...) name
#define _rep_rev(i, a) repi_rev(i, 0, a)
#define repi_rev(i, a, b)                                                      \
    for (long long i = (long long)(b)-1; i >= (long long)(a); --i)
#define rrep(...) _overload3_rev(__VA_ARGS__, repi_rev, _rep_rev)(__VA_ARGS__)

#define all(n) begin(n), end(n)
template <typename T, typename E> bool chmin(T &s, const E &t) {
    bool res = s > t;
    s = min<T>(s, t);
    return res;
}
template <typename T, typename E> bool chmax(T &s, const E &t) {
    bool res = s < t;
    s = max<T>(s, t);
    return res;
}
const vector<lint> dx = {1, 0, -1, 0, 1, 1, -1, -1};
const vector<lint> dy = {0, 1, 0, -1, 1, -1, 1, -1};
#define SUM(v) accumulate(all(v), 0LL)
#if __cplusplus >= 201703L
template <typename T, typename... Args>
auto make_vector(T x, int arg, Args... args) {
    if constexpr (sizeof...(args) == 0)
        return vector<T>(arg, x);
    else
        return vector(arg, make_vector<T>(x, args...));
}
#endif
#define bit(n, a) ((n >> a) & 1)
#define extrep(v, ...) for (auto v : make_mat_impl({__VA_ARGS__}))
vector<vector<long long>> make_mat_impl(vector<long long> v) {
    if (v.empty())
        return vector<vector<long long>>(1, vector<long long>());
    long long n = v.back();
    v.pop_back();
    vector<vector<long long>> ret;
    vector<vector<long long>> tmp = make_mat_impl(v);
    for (auto e : tmp)
        for (long long i = 0; i < n; ++i) {
            ret.push_back(e);
            ret.back().push_back(i);
        }
    return ret;
}
using graph = vector<vector<int>>;
template <typename T> using graph_w = vector<vector<pair<int, T>>>;

#if __cplusplus >= 201703L
constexpr inline long long powll(long long a, long long b) {
    long long res = 1;
    while (b--)
        res *= a;
    return res;
}
#endif

template <typename T, typename E>
pair<T, E> &operator+=(pair<T, E> &s, const pair<T, E> &t) {
    s.first += t.first;
    s.second += t.second;
    return s;
}
template <typename T, typename E>
pair<T, E> &operator-=(pair<T, E> &s, const pair<T, E> &t) {
    s.first -= t.first;
    s.second -= t.second;
    return s;
}
template <typename T, typename E>
pair<T, E> operator+(const pair<T, E> &s, const pair<T, E> &t) {
    auto res = s;
    return res += t;
}
template <typename T, typename E>
pair<T, E> operator-(const pair<T, E> &s, const pair<T, E> &t) {
    auto res = s;
    return res -= t;
}
#define BEGIN_STACK_EXTEND(size)                                               \
    void *stack_extend_memory_ = malloc(size);                                 \
    void *stack_extend_origin_memory_;                                         \
    char *stack_extend_dummy_memory_ = (char *)alloca(                         \
        (1 + (int)(((long long)stack_extend_memory_) & 127)) * 16);            \
    *stack_extend_dummy_memory_ = 0;                                           \
    asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp"                          \
                 : "=b"(stack_extend_origin_memory_)                           \
                 : "a"((char *)stack_extend_memory_ + (size)-1024));
#define END_STACK_EXTEND                                                       \
    asm volatile("mov %%rax, %%rsp" ::"a"(stack_extend_origin_memory_));       \
    free(stack_extend_memory_);
int floor_pow(int n) { return n ? 31 - __builtin_clz(n) : 0; }
#line 2 "main.cpp"

void solve() {
    lint n;
    cin >> n;
    vec a(n);
    rep(i, n) cin >> a[i];
    map<lint, lint> m;
    vec ans;
    rep(i, n) {
        m[a[i]]++;
        if (m[a[i]] == 0) {
            m.erase(a[i]);
        }
        m[a[n - 1 - i]]--;
        if (m[a[n - 1 - i]] == 0) {
            m.erase(a[n - 1 - i]);
        }
        if (m.empty())
            ans.emplace_back(i + 1);
    }
    output(ans);
}

int main() { solve(); }
accuracy: 1
time_ms: 50
memory_kb: 5036
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) (a).begin(), a.end()
#define rep(i,n) for(ll i = 0; i < n; i++)

int main(){
    int n;
    cin >> n;
    vector<int> a(n);
    rep(i,n) cin >> a[i];
    map<int,int> cnt;

    int ok = 0;
    vector<int> ans;
    rep(i,n){
        if(cnt[a[i]] == 0) ok++;
        cnt[a[i]] += 1;
        if(cnt[a[i]] == 0) ok--;
        if(cnt[a[n-1-i]] == 0) ok++;
        cnt[a[n-1-i]] -= 1;
        if(cnt[a[n-1-i]] == 0) ok--;

        if(ok == 0){
            ans.emplace_back(i+1);
        }
    }
    
    for(int i = 0; i < ans.size(); i++){
        cout << ans[i] << " \n"[i == ans.size() - 1];
    }
}
accuracy: 1
time_ms: 70
memory_kb: 5780
final_rank: 10

code_snippet: #include "bits/stdc++.h"
using namespace std;

#define REP(i, n) for(ll i = 0;i < n;i++)
#define REPR(i, n) for(ll i = n;i >= 0;i--)
#define FOR(i, m, n) for(ll i = m;i < n;i++)
#define FORR(i, m, n) for(ll i = m;i >= n;i--)
#define REPO(i, n) for(ll i = 1;i <= n;i++)
#define ll long long
#define INF (ll)1ll << 60
#define MINF (-1 * INF)
#define ALL(n) n.begin(),n.end()
#define MOD (ll)1000000007
#define P pair<ll, ll>

ll n, cnt = 0;
map<ll, ll> mp;
int main(){
    cin >> n;
    vector<ll> s(n), ans;
    REP(i, n){
        cin >> s[i];
    }
    REP(i, n){
        if(s[i] != s[n - 1 - i]){
            if (mp[s[i]] == 0) cnt++;
            if (mp[s[n - 1 - i]] == 0) cnt++;
            mp[s[i]]++;
            mp[s[n - 1 - i]]--;
            if (mp[s[i]] == 0) cnt--;
            if (mp[s[n - 1 - i]] == 0) cnt--;
        }
        if (cnt == 0) ans.push_back(i + 1);
    }
    REP(i, ans.size()){
        if (i != 0) cout << " ";
        cout << ans[i];
    }
    cout << endl;
}
accuracy: 1
time_ms: 80
memory_kb: 6840
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
constexpr int MOD=998244353;

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int N;
  cin>>N;
  vector A(N,0);
  for(int &i:A)cin>>i;
  map<int,int>cnt;
  int ng=0;
  vector ans(0,0);
  for(int i=0;i<N;i++){
    if(cnt[A[i]]==0){
      ng+=1;
    }
    cnt[A[i]]+=1;
    if(cnt[A[N-1-i]]==1){
      ng-=1;
    }
    cnt[A[N-1-i]]-=1;
    if(ng==0){
      ans.push_back(i+1);
    }
  }
  for(int i=0;i<ans.size();i++){
    cout<<ans[i]<<(i==(int)ans.size()-1?'\n':' ');
  }
}
accuracy: 1
time_ms: 40
memory_kb: 5736
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

int main(){
  ll N;
  cin >> N;
  vector<ll> A(N);
  for(int i=0; i<N; i++) cin >> A[i];
  map<ll,ll> mp;
  ll cnt = 0;
  vector<ll> ans;
  for(int i=0; i<N; i++){
    if(mp[A[i]] == 0){
      cnt++;
    }
    mp[A[i]]++;
    if(mp[A[i]] == 0){
      cnt--;
    }
    if(mp[A[N-1-i]] == 0){
      cnt++;
    }
    mp[A[N-1-i]]--;
    if(mp[A[N-1-i]] == 0){
      cnt--;
    }
    if(cnt == 0){
      ans.emplace_back(i+1);
    }
  }
  for(int i=0; i<ans.size(); i++){
    cout << ans[i] << " \n"[i+1==ans.size()];
  }
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 6936
final_rank: 16