#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define sz(x) int((x).size())
#define fi first
#define se second
typedef long long ll;
typedef pair<int, int> ii;
template<class X, class Y>
inline bool maximize(X &x, const Y &y) {return (x < y ? x = y, 1 : 0);}
template<class X, class Y>
inline bool minimize(X &x, const Y &y) {return (x > y ? x = y, 1 : 0);}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int Random(int l, int r) {
return uniform_int_distribution<int>(l, r)(rng);
}
const int MAXN = 1000006;
const int NMOD = 2;
const int BASE = 2000006;
const int MOD[] = {int(1e9) + 2277, int(1e9) + 5277, int(1e9) + 8277, int(1e9) + 9277};
ll pw[NMOD][MAXN];
struct Hash {
ll value[NMOD];
Hash(int c = 0) {
for (int i = 0; i < NMOD; ++i)
value[i] = c;
}
Hash& operator += (const Hash &h) {
for (int i = 0; i < NMOD; ++i) {
if((value[i] += h.value[i]) >= MOD[i])
value[i] -= MOD[i];
}
return (*this);
}
Hash operator + (const Hash &h) const {
Hash res = (*this);
return res += h;
}
Hash& operator -= (const Hash &h) {
for (int i = 0; i < NMOD; ++i) {
if((value[i] -= h.value[i]) < 0)
value[i] += MOD[i];
}
return (*this);
}
Hash operator - (const Hash &h) const {
Hash res = (*this);
return res -= h;
}
Hash operator * (int k) const {
Hash res;
for (int i = 0; i < NMOD; ++i)
res.value[i] = value[i] * pw[i][k] % MOD[i];
return res;
}
bool operator == (const Hash &h) const {
for (int i = 0; i < NMOD; ++i) {
if(value[i] != h.value[i])
return false;
}
return true;
}
bool operator < (const Hash &h) const {
for (int i = 0; i < NMOD; ++i) {
if(value[i] != h.value[i])
return value[i] < h.value[i];
}
return false;
}
} hashVal[MAXN], rhashVal[MAXN];
int lab[MAXN];
set<int> S[MAXN];
vector<int> adj[MAXN], idx;
map<Hash, int> Map;
map<int, int> cnt[MAXN];
int p[MAXN], q[MAXN], cntBadComp, nArr, numQuery;
ll result;
int root(int u) {
return (lab[u] < 0) ? u : (lab[u] = root(lab[u]));
}
int getSize(int u) {
return -lab[root(u)];
}
Hash goodCompHash;
inline bool isBadComp(int u) {
return (!(hashVal[u] == rhashVal[u]));
}
ll calc(int u) {
u = root(u);
if(!isBadComp(u))
return 0;
return Map[rhashVal[u]];
}
void modifyVal(int u, int k, int val) {
u = root(u);
if(val > 0) {
hashVal[u] += Hash(1) * k;
rhashVal[u] -= Hash(1) * k;
} else {
hashVal[u] -= Hash(1) * k;
rhashVal[u] += Hash(1) * k;
}
}
void removeComp(int u) {
u = root(u);
cntBadComp -= isBadComp(u);
result -= 1LL * getSize(u) * calc(u);
Map[hashVal[u]] -= getSize(u);
hashVal[u] = 0, rhashVal[u] = 1;
}
void swapPos(int u, int v) {
int ru(root(u)), rv(root(v));
if(ru == rv) {
swap(p[u], p[v]);
return;
}
cntBadComp -= int(isBadComp(ru)) + isBadComp(rv);
result -= 1LL * getSize(ru) * calc(ru);
Map[hashVal[ru]] -= getSize(ru);
result -= 1LL * getSize(rv) * calc(rv);
Map[hashVal[rv]] -= getSize(rv);
modifyVal(ru, p[u], -1), modifyVal(rv, p[v], -1);
swap(p[u], p[v]);
modifyVal(ru, p[u], 1), modifyVal(rv, p[v], 1);
Map[hashVal[rv]] += getSize(rv);
result += 1LL * getSize(ru) * calc(ru) + 1LL * getSize(rv) * calc(rv);
Map[hashVal[ru]] += getSize(ru);
cntBadComp += int(isBadComp(ru)) + isBadComp(rv);
}
bool join(int u, int v) {
u = root(u), v = root(v);
if(u == v)
return (false);
if(lab[u] > lab[v])
swap(u, v);
cntBadComp -= isBadComp(u);
result -= 1LL * getSize(u) * calc(u);
Map[hashVal[u]] -= getSize(u); Hash tmp(hashVal[u]); hashVal[u] = 0;
removeComp(v); hashVal[u] = tmp;
lab[u] += lab[v];
lab[v] = u;
for (int it = 0; it < sz(adj[v]); ++it) {
int c(adj[v][it]);
hashVal[u] += Hash(1) * p[c] - Hash(1) * q[c];
rhashVal[u] -= Hash(1) * p[c] - Hash(1) * q[c];
adj[u].push_back(c);
}
Map[hashVal[u]] += getSize(u);
cntBadComp += isBadComp(u);
result += 1LL * getSize(u) * calc(u);
return (true);
}
void prepare(void) {
for (int i = 0; i < NMOD; ++i) {
pw[i][0] = 1;
for (int j = 1; j <= nArr; ++j)
pw[i][j] = pw[i][j - 1] * BASE % MOD[i];
}
goodCompHash = 0;
for (int j = 1; j <= nArr; ++j)
goodCompHash += Hash(nArr) * j;
}
void process() {
cin >> nArr >> numQuery; //nArr = 2000, numQuery = 10000;
for (int i = 1; i <= nArr; ++i) {
cin >> p[i];
//p[i] = Random(1, nArr); cout << p[i] << " \n"[i == nArr];
idx.push_back(p[i]);
lab[i] = -1;
}
sort(idx.begin(), idx.end());
idx.erase(unique(idx.begin(), idx.end()), idx.end());
for (int i = 1; i <= nArr; ++i)
p[i] = q[i] = upper_bound(idx.begin(), idx.end(), p[i]) - idx.begin();
prepare();
sort(q + 1, q + nArr + 1);
for (int i = 1; i <= nArr; ++i) {
cntBadComp += (p[i] != q[i]);
hashVal[i] = goodCompHash + Hash(1) * p[i] - Hash(1) * q[i];
rhashVal[i] = goodCompHash - Hash(1) * p[i] + Hash(1) * q[i];
//cout << "+ " << p[i] << ' ' << i << '\n';
//cout << "- " << q[i] << ' ' << i << '\n';
adj[i].push_back(i);
++Map[hashVal[i]];
result += calc(i);
}
//cout << goodCompHash.value[0] << '\n';
for (int t = 0; t < numQuery; ++t) {
int type, A, B;
cin >> type;
//type = Random(1, 4); cout << type << ' ';
if(type <= 2) {
cin >> A >> B;
//A = Random(1, nArr - 1), B = Random(A + 1, nArr); cout << A << ' ' << B << '\n';
}
if(type == 1) {
swapPos(A, B);
} else
if(type == 2) {
join(A, B);
} else
if(type == 3) {
cout << (cntBadComp == 0 ? "DA" : "NE") << '\n';
} else {
cout << result << '\n';
}
}
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
process();
return 0;
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
58 ms |
149064 KB |
Output is correct |
2 |
Correct |
63 ms |
149104 KB |
Output is correct |
3 |
Correct |
59 ms |
148980 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
65 ms |
149032 KB |
Output is correct |
2 |
Correct |
58 ms |
148996 KB |
Output is correct |
3 |
Correct |
59 ms |
149084 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
57 ms |
149088 KB |
Output is correct |
2 |
Correct |
57 ms |
149100 KB |
Output is correct |
3 |
Correct |
58 ms |
149020 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
59 ms |
149120 KB |
Output is correct |
2 |
Correct |
65 ms |
149124 KB |
Output is correct |
3 |
Correct |
60 ms |
149188 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
65 ms |
149076 KB |
Output is correct |
2 |
Correct |
60 ms |
149100 KB |
Output is correct |
3 |
Correct |
58 ms |
149228 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
67 ms |
149780 KB |
Output is correct |
2 |
Correct |
67 ms |
149788 KB |
Output is correct |
3 |
Correct |
71 ms |
149816 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
120 ms |
155824 KB |
Output is correct |
2 |
Correct |
154 ms |
157424 KB |
Output is correct |
3 |
Correct |
186 ms |
160624 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1125 ms |
198196 KB |
Output is correct |
2 |
Correct |
3866 ms |
288956 KB |
Output is correct |
3 |
Correct |
4915 ms |
339792 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2025 ms |
254136 KB |
Output is correct |
2 |
Correct |
3460 ms |
275104 KB |
Output is correct |
3 |
Correct |
1656 ms |
262620 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1058 ms |
219796 KB |
Output is correct |
2 |
Correct |
2355 ms |
259000 KB |
Output is correct |
3 |
Correct |
1666 ms |
262720 KB |
Output is correct |