题目链接:https://www.luogu.org/problemnew/show/P2709
求(cnt表示a[i]出现的次数),ans = (cnt[a[i]] + 1) ^2 - (cnt[a[i]]^2)
(把add,del单独写成两个函数,转移过程用位运算会更快一点)
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <map> #include <set> #include <vector> #include <string> #include <cmath> #define rep(i, s, e) for(int i = s; i < e; ++i) #define P pair<int, int> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; static const int MAX_N = 5e4 + 5; static const ll Mod = 1e9 + 7; struct Query{ int l, r, id, pos; bool operator < (Query &q)const{ if(pos == q.pos) return r < q.r; return pos < q.pos; } }q[MAX_N]; ll rev[MAX_N]; int cnt[MAX_N], a[MAX_N]; ll ans; void update(int p, int v){ ans -= cnt[a[p]] * cnt[a[p]]; cnt[a[p]] += v; ans += cnt[a[p]] * cnt[a[p]]; } void solve(){ int n, m, k; scanf("%d%d%d", &n, &m, &k); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); int block = (int)sqrt(n); for(int i = 1; i <= m; ++i){ scanf("%d%d", &q[i].l, &q[i].r); q[i].id = i; q[i].pos = (q[i].l - 1) / block + 1; } sort(q + 1, q + m + 1); int l = 1, r = 0; for(int i = 1; i <= m; ++i){ while(l < q[i].l) update(l++, -1); while(l > q[i].l) update(--l, 1); while(r < q[i].r) update(++r, 1); while(r > q[i].r) update(r--, -1); rev[q[i].id] = ans; } for(int i = 1; i <= m; ++i) printf("%lld\n", rev[i]); } int main(){ // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); solve(); return 0; }