2024年3月19日 莫隊 + CF div3

O_JF?發表於2024-03-20

參考 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 題意不清 + 樣例能過 + 卡題 + 心態 => 掉分