基础莫队模板

记录一下莫队的板子

基础莫队

入门题 小z的袜子 

#include 
#define int long long
#define endl '\n'
#define sz(x) x.size()
#define lbt(x) (x)&(-x)
#define rep(i,n) for(int i=0;i PII;
typedef double db;
const int N = 5e4 + 10, mod = 998244353, inf = 0x3f3f3f3f;
const db EPS = 1e-9;
int res[N], a[N], id[N], cnt[N], len[N];
struct Q {
  int l, r, k;
}q[N];
int tmp;
void add(int x) {
  tmp += cnt[a[x]];
  cnt[a[x]]++;
}
void del(int x) {
  cnt[a[x]]--;
  tmp -= cnt[a[x]];
}
void solve() {
  int n, m;
  cin >> n >> m;
  int dk = sqrt(n);
  for (int i = 1;i <= n;i++) {
    id[i] = (i - 1) / dk + 1;
    cin >> a[i];
  }
  for (int i = 1;i <= m;i++) {
    int l, r;
    cin >> l >> r;
    len[i] = (r - l + 1) * (r - l) / 2;
    q[i] = { l,r,i };
  }
  sort(q + 1, q + 1 + m, [&](Q a, Q b) {
    if (id[a.l] == id[b.l])return a.r < b.r;
    return id[a.l] < id[b.l];
    });
  int l = 1, r = 0;
  for (int i = 1;i <= m;i++) {
    while (l > q[i].l) add(--l);
    while (r < q[i].r) add(++r);
    while (l < q[i].l) del(l++);
    while (r > q[i].r) del(r--);
    res[q[i].k] = tmp;
  }
  for (int i = 1;i <= m;i++) {
    int d = __gcd(res[i], len[i]);
    if (d == 0)
      cout << "0/1" << endl;
    else
      cout << res[i] / d << "/" << len[i] / d << endl;
  }
}

signed main() {
  cin.tie(0)->sync_with_stdio(0);
  cout.tie(0);
  int _ = 1;
  // cin >> _ ;
  while (_--)
    solve();
  return 0;
}
区间众数问题
2021 江西省赛 G Magic Number Group
查询区间中出现次数最多的质因数
#include 
// #define int long long
#define endl '\n'
#define sz(x) x.size()
#define lbt(x) (x)&(-x)
#define rep(i,n) for(int i=0;i PII;
typedef double db;
const int N = 5e5 + 10, mod = 998244353, inf = 0x3f3f3f3f;
const db EPS = 1e-9;
int res[N], a[N], id[N], cnt[N], len[N], num[N];
vectorfac[N];
struct Q {
    int l, r, k;
}q[N];
int tmp, mx;
void init(int n) {
    for (int i = 1;i <= n;i++) fac[i].clear();
}
void work(vector& v, int x) {
    for (int i = 2;i <= x / i;i++) {
        if (x % i)continue;
        while (x % i == 0)x /= i;
        v.push_back(i);
    }
    if (x > 1)v.push_back(x);
}
void add(int x) {
    for (auto t : fac[x]) {
        --num[cnt[t]], ++num[++cnt[t]];
        while (num[tmp + 1])tmp++;
    }
}
void del(int x) {
    for (auto t : fac[x]) {
        --num[cnt[t]], ++num[--cnt[t]];
        while (!num[tmp])tmp--;
    }
}
void solve() {
    int n, m;
    cin >> n >> m;
    init(n);
    int dk = sqrt(n);
    for (int i = 1;i <= n;i++) {
        id[i] = (i - 1) / dk + 1;
        cin >> a[i];
        work(fac[i], a[i]);
    }
    for (int i = 1;i <= m;i++) {
        int l, r;
        cin >> l >> r;
        len[i] = (r - l + 1) * (r - l) / 2;
        q[i] = { l,r,i };
    }
    sort(q + 1, q + 1 + m, [&](Q a, Q b) {
        if (id[a.l] == id[b.l])return a.r < b.r;
        return id[a.l] < id[b.l];
        });
    num[0] = 1;
    int l = 1, r = 0;
    for (int i = 1;i <= m;i++) {
        while (l > q[i].l) add(--l);
        while (r < q[i].r) add(++r);
        while (l < q[i].l) del(l++);
        while (r > q[i].r) del(r--);
        res[q[i].k] = tmp;
    }
    while (l <= r)del(r--);
    for (int i = 1;i <= m;i++) {
        cout << res[i] << endl;
    }
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    cout.tie(0);
    int _ = 1;
    cin >> _ ;
    while (_--)
        solve();
    return 0;
}

带修莫队

洛谷 P1903 [国家集训队] 数颜色 / 维护队列

单点修改,区间查询不同的数的个数

#include 
#define int long long
#define endl '\n'
#define sz(x) x.size()
#define lbt(x) (x)&(-x)
#define rep(i,n) for(int i=0;i PII;
typedef double db;
const int N = 2e5 + 10, M = 2e6, mod = 998244353, inf = 0x3f3f3f3f;
const db EPS = 1e-9;
int res[N], a[N], id[N], cnt[M];
int cc1, cc2, tmp;
struct Q {
    int l, r, t, k;
}q[N], qr[N];
void add(int x) {
    tmp += !cnt[x]++;
}
void del(int x) {
    tmp -= !--cnt[x];
}
void work(int x, int t) {
    if (q[x].l <= qr[t].l && qr[t].l <= q[x].r) {
        del(a[qr[t].l]);
        add(qr[t].r);
    }
    swap(a[qr[t].l], qr[t].r);
}

void solve() {
    int n, m;
    cin >> n >> m;
    int dk = pow(n, 0.666);
    for (int i = 1;i <= n;i++) {
        id[i] = (i - 1) / dk + 1;
        cin >> a[i];
    }
    for (int i = 1;i <= m;i++) {
        string op;int l, r, x;
        cin >> op;
        if (op[0] == 'Q') {
            cin >> l >> r;
            ++cc1;
            q[cc1] = { l,r,cc2,cc1 };
        }
        else {
            cin >> l >> x;
            ++cc2;
            qr[cc2] = { l,x };
        }
    }
    sort(q + 1, q + 1 + cc1, [&](Q a, Q b) {
        if (id[a.l] == id[b.l])return id[a.r] == id[b.r] ? a.t < b.t : id[a.r] < id[b.r];
        return id[a.l] < id[b.l];
        });
    int l = 1, r = 0, t = 0;
    for (int i = 1;i <= cc1;i++) {
        while (l > q[i].l)add(a[--l]);
        while (l < q[i].l)del(a[l++]);
        while (r < q[i].r)add(a[++r]);
        while (r > q[i].r)del(a[r--]);
        while (t < q[i].t)work(i, ++t);
        while (t > q[i].t)work(i, t--);
        res[q[i].k] = tmp;
    }
    for (int i = 1;i <= cc1;i++)cout << res[i] << endl;
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    cout.tie(0);
    int _ = 1;
    // cin >> _;
    while (_--)
        solve();
    return 0;
}

你可能感兴趣的:(c++,c语言,数据结构)