參考 https://www.cnblogs.com/WAMonster/p/10118934.html ,寫得很好
//普通莫隊演算法
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
const int SN=1e7+10;
int a[N],ans[N],cnt[N],sum,sz;
struct node{
int l,r,id;
}q[N];
bool operator<(node a,node b){
return a.l/sz == b.l/sz
? (a.l/sz)&1 ? a.r < b.r : a.r > b.r
: a.l < b.l;
}
inline void add(int x) {sum+=!cnt[x]++;}
inline void del(int x) {sum-=!--cnt[x];}
void solve() {
int n; cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
int m; cin >> m;
for (int i = 1; i <= m; i++) {
q[i].id = i;
cin >> q[i].l >> q[i].r;
}
sz=pow(n,0.666);
sort(q+1,q+m+1);
int l=1,r=0;
for (int i = 1; i <= m; i++){
auto [ql,qr,id] = q[i];
while (l > q[i].l) add(a[--l]);
while (l < q[i].l) del(a[l++]);
while (r > q[i].r) del(a[r--]);
while (r < q[i].r) add(a[++r]);
ans[id]=sum;
}
for (int i = 1; i <= m; i++) {
cout << ans[i] << '\n';
}
}
signed main() {
ios::sync_with_stdio(false);cin.tie(0);
solve();
}
//強制線上莫隊演算法
#include<bits/stdc++.h>
using namespace std;
#define N 233333
#define M 1111111
int sum, cnt[M], a[N], ans[N], sz;
struct ques {
int l, r, t, id;
} qq[N], qr[N];
inline void add(int x) {sum+=!cnt[x]++;}
inline void del(int x) {sum-=!--cnt[x];}
inline void upd(int x, int t) {
if (qq[x].l<=qr[t].l&&qr[t].l<=qq[x].r) {
del(a[qr[t].l]);
add(qr[t].r);
}
swap(a[qr[t].l], qr[t].r);
}
bool cmp (const ques &a, const ques &b) {
return a.l/sz==b.l/sz
? a.r/sz==b.r/sz ? a.t<b.t : a.r<b.r
: a.l<b.l;
}
int main() {
int n, m;
cin >> n >> m;
sz = pow(n, 0.666);
int cntq = 0, cntr = 0;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= m; i++){
char op;
int l, r;
cin>> op >> l >> r;
if (op == 'Q') {
++cntq;
qq[cntq].id = cntq;
qq[cntq].t = cntr;
qq[cntq].l = l, qq[cntq].r = r;
}
else qr[++cntr].l = l, qr[cntr].r = r;
}
sort(qq + 1, qq + cntq + 1, cmp);
int l = 1, r = 0, t = 0;
for (int i = 1; i <= cntq; i++) {
while (l > qq[i].l) add(a[--l]);
while (l < qq[i].l) del(a[l++]);
while (r > qq[i].r) del(a[r--]);
while (r < qq[i].r) add(a[++r]);
while (t < qq[i].t) upd(i, ++t);
while (t > qq[i].t) upd(i, t--);
ans[qq[i].id] = sum;
}
for (int i = 1; i <= cntq; i++) cout << ans[i] << '\n';
return 0;
}
div 3 題意不清 + 樣例能過 + 卡題 + 心態 => 掉分