luogu P2709 小B的询问
二次联通门 : luogu P2709 小B的询问
/* luogu P2709 小B的询问 莫队.. 维护每个数的出现次数 每次更新时先减去出现次数的平方 后加上 加or减 后的平方即可 */ #include <algorithm> #include <cstdio> #include <cmath> #define Max 500090 inline void read (int &now) { now = 0; register char word = getchar (); while (word < '0' || word > '9') word = getchar (); while (word >= '0' && word <= '9') { now = now * 10 + word - '0'; word = getchar (); } } int N, M, K; int Result; int number[Max]; int count[Max]; int K_Size; int belong[Max]; struct Query_Data { int l, r; int Id; bool operator < (const Query_Data &now) const { if (belong[now.l] == belong[this->l]) return this->r < now.r; return belong[this->l] < belong[now.l]; } }; Query_Data query[Max]; inline void Updata (int now, bool type) { if (type) { Result -= count[number[now]] * count[number[now]]; count[number[now]] ++; Result += count[number[now]] * count[number[now]]; } else { Result -= count[number[now]] * count[number[now]]; count[number[now]] --; Result += count[number[now]] * count[number[now]]; } } int Answer[Max]; int main (int argc, char *argv[]) { read (N); read (M); read (K); K_Size = sqrt (N); for (int i = 1; i <= N; i ++) { belong[i] = (i + 1) / K_Size; read (number[i]); } for (int i = 1; i <= M; i ++) { read (query[i].l); read (query[i].r); query[i].Id = i; } std :: sort (query + 1, query + 1 + M); int l = 1, r = 0; for (int i = 1; i <= M; i ++) { while (l < query[i].l) Updata (l ++, false); while (l > query[i].l) Updata (-- l, true); while (r < query[i].r) Updata (++ r, true); while (r > query[i].r) Updata (r --, false); Answer[query[i].Id] = Result; } for (int i = 1; i <= M; i ++) printf ("%d\n", Answer[i]); return 0; }
myj 吊打我Orz,xxy 捆起来打我Orz,myl 文化课上天Orz, lrh 姿势水平敲高Orz, hkd 特别胖Orz%%%,cys 智商感人Orz,syl zz专业Orz,我没有学上, 我们未来一片光明