首页 > 代码库 > luogu P1972 [SDOI2009]HH的项链
luogu P1972 [SDOI2009]HH的项链
二次联通门 : luogu P1972 [SDOI2009]HH的项链
/* luogu P1972 [SDOI2009]HH的项链 莫队水过 记录一个count数组 来记录每个数出现了几次 缩小区间时只要看是否只出现一次 扩张区间时只要看看是否出现过即可 */ #include <algorithm> #include <cstdio> #include <cmath> #define Max 1000001 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 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; else return belong[this->l] < belong[now.l]; } }; int N, M; int number[Max]; Query_Data query[Max]; int count[Max]; int Result; bool visit[Max]; inline void Updata (int now, bool type) { if (type) { if (!count[number[now]]) Result ++; count[number[now]] ++; } else { if (count[number[now]] == 1) Result --; count[number[now]] --; } } int Answer[Max]; int main (int argc, char *argv[]) { read (N); int Size = sqrt (N); for (int i = 1; i <= N; i ++) { read (number[i]); belong[i] = (i + 1) / Size; } read (M); 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 ++) { if (l < query[i].l) for (int pos = l; pos < query[i].l; pos ++) Updata (pos, false); else if (l >= query[i].l) for (int pos = l - 1; pos >= query[i].l; pos --) Updata (pos, true); if (r > query[i].r) for (int pos = r; pos > query[i].r; pos--) Updata (pos, false); else if (r <= query[i].r) for (int pos = r + 1; pos <= query[i].r; pos++) Updata (pos, true); l = query[i].l; r = query[i].r; Answer[query[i].Id] = Result; } for (int i = 1; i <= M; i ++) printf ("%d\n", Answer[i]); return 0; }
luogu P1972 [SDOI2009]HH的项链
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。