This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#define fast ios::sync_with_stdio(0);cin.tie(0);
#define s second
#define f first
typedef long long ll;
const ll MOD = 1e9 + 9;
const ll LOGN = 21;
const ll MAXN = 1e6 + 100;
#define int long long
const ll P = 1322131;
const ll P2 = 14342481;
vector<int> A, B;
ll expo(ll a, ll b) {
ll res = 1;
while (b) {
if (b & 1)
res = (res * a) % MOD;
a = (a * a) % MOD;
b /= 2;
}
return res;
}
pair<ll,ll> Hash(ll x) {
return {expo(x, P), expo(x, P2)};
}
int ans4 = 0;
int not_equal = 0;
map<pair<ll,ll>,int> cnt;
int par[MAXN], sz[MAXN];
pair<int,int> st[MAXN];
int find(int node) {
if (node == par[node])
return node;
return par[node] = find(par[node]);
}
void unite(int a, int b) {
a = find(a);
b = find(b);
if (a == b)
return ;
if (sz[b] > sz[a])
swap(a, b);
par[b] = a;
if (st[a].f || st[a].s)
ans4 -= cnt[{MOD - st[a].f, MOD - st[a].s}] * sz[a];
if (st[b].f || st[b].s)
ans4 -= cnt[{MOD - st[b].f, MOD - st[b].s}] * sz[b];
ans4 += ((((st[a].f + st[b].f) % MOD) == 0 && ((st[a].s + st[b].s) % MOD) == 0 && (st[a].f != 0 || st[a].s != 0)) ? sz[a] * sz[b] : 0);
cnt[st[a]] -= sz[a];
cnt[st[b]] -= sz[b];
sz[a] += sz[b];
not_equal -= (st[a].f != 0 || st[a].s != 0) + (st[b].f != 0 || st[b].s != 0);
st[a] = {(st[a].f + st[b].f) % MOD, (st[a].s + st[b].s) % MOD};
cnt[st[a]] += sz[a];
if (st[a].f != 0 || st[b].f != 0)
ans4 += cnt[{MOD - st[a].f, MOD - st[a].s}] * sz[a];
not_equal += (st[a].f != 0 || st[a].s != 0);
}
void swp(int a, int b) {
int parA = find(a);
int parB = find(b);
if (st[parA].f || st[parA].s)
ans4 -= cnt[{MOD - st[parA].f, MOD - st[parA].s}] * sz[parA];
if ((st[parB].f || st[parB].s) && parB != parA)
ans4 -= cnt[{MOD - st[parB].f, MOD - st[parB].s}] * sz[parB];
if (parB != parA)
ans4 += ((((st[parA].f + st[parB].f) % MOD) == 0 && ((st[parA].s + st[parB].s) % MOD) == 0 && (st[parA].f != 0 || st[parA].s != 0)) ? sz[parA] * sz[parB] : 0);
cnt[st[parA]] -= sz[parA];
if (parA != parB)
cnt[st[parB]] -= sz[parB];
not_equal -= (st[parA].f != 0 || st[parA].s != 0) + (st[parB].f != 0 || st[parB].s != 0);
st[parA] = {(st[parA].f - Hash(A[a]).f + Hash(A[b]).f) % MOD, (st[parA].s - Hash(A[a]).s + Hash(A[b]).s) % MOD};
st[parB] = {(st[parB].f - Hash(A[b]).f + Hash(A[a]).f) % MOD, (st[parB].s - Hash(A[b]).s + Hash(A[a]).s) % MOD};
if (st[parA].f < 0) st[parA].f += MOD;
if (st[parA].s < 0) st[parA].s += MOD;
if (st[parB].f < 0) st[parB].f += MOD;
if (st[parB].s < 0) st[parB].s += MOD;
cnt[st[parA]] += sz[parA];
if (parA != parB)
cnt[st[parB]] += sz[parB];
if (st[parA].f || st[parA].s)
ans4 += cnt[{MOD - st[parA].f, MOD - st[parA].s}] * sz[parA];
if ((st[parB].f || st[parB].s) && parB != parA)
ans4 += cnt[{MOD - st[parB].f, MOD - st[parB].s}] * sz[parB];
if (parB != parA)
ans4 -= ((((st[parA].f + st[parB].f) % MOD) == 0 && ((st[parA].s + st[parB].s) % MOD) == 0 && (st[parA].f != 0 || st[parA].s != 0)) ? sz[parA] * sz[parB] : 0);
swap(A[a], A[b]);
not_equal += (st[parA].f != 0 || st[parA].s != 0) + (st[parB].f != 0 || st[parB].s != 0);
}
signed main() {
fast
int N, Q;
cin >> N >> Q;
A = vector<int>(N+1);
for (int i = 1; i <= N; i++) {
cin >> A[i];
B.push_back(A[i]);
}
sort(B.begin(), B.end(), greater<int>());
B.push_back(0);
reverse(B.begin(), B.end());
for (int i = 1; i <= N; i++) {
par[i] = i;
pair<int,int> H1 = Hash(A[i]);
pair<int,int> H2 = Hash(B[i]);
st[i] = {H1.f - H2.f, H1.s - H2.s};
sz[i] = 1;
if (st[i].f < 0)
st[i].f += MOD;
if (st[i].s < 0)
st[i].s += MOD;
cnt[st[i]]++;
not_equal += (st[i].f != 0 || st[i].s != 0);
}
for (auto u : cnt) {
if (u.f.f >= MOD - u.f.f)
continue;
ans4 += u.s * cnt[make_pair(MOD - u.f.f, MOD - u.f.s)];
}
while (Q--) {
int T, A, B;
cin >> T;
if (T == 1) {
cin >> A >> B;
swp(A, B);
} else if (T == 2) {
cin >> A >> B;
unite(A, B);
} else if (T == 3)
cout << (not_equal == 0 ? "DA\n" : "NE\n");
else
cout << ans4 << "\n";
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |