BZOJ 1878:[SDOI2009]HH的项链(莫队算法)
http://www.lydsy.com/JudgeOnline/problem.php?id=1878
题意:……
思路:比上题还简单很多。数字很小,开一个数组哈希记录出现次数(记得数组要开1e6),然后直接算就行了。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 #define N 50010 7 struct node { 8 int l, r, ans, id; 9 } p[N*4]; 10 int mp[N*20], num[N], ans, kuai; 11 12 bool cmp(const node &a, const node &b) { 13 if(a.l / kuai == b.l / kuai) return a.r < b.r; 14 return a.l / kuai < b.l / kuai; 15 } 16 17 bool cmpid(const node &a, const node &b) { 18 return a.id < b.id; 19 } 20 21 void update(int id, int w) { 22 if(mp[num[id]]) ans--; mp[num[id]] += w; if(mp[num[id]]) ans++; 23 } 24 25 int main() { 26 int n, m; 27 while(~scanf("%d", &n)) { 28 for(int i = 1; i <= n; i++) scanf("%d", num + i); 29 scanf("%d", &m); 30 for(int i = 1; i <= m; i++) scanf("%d%d", &p[i].l, &p[i].r), p[i].id = i; 31 kuai = sqrt(n); ans = 0; 32 memset(mp, 0, sizeof(mp)); 33 sort(p + 1, p + 1 + m, cmp); 34 for(int L = 1, R = 0, i = 1; i <= m; i++) { 35 int l = p[i].l, r = p[i].r; 36 for( ; L < l; L++) update(L, -1); 37 for( ; L > l; L--) update(L - 1, 1); 38 for( ; R < r; R++) update(R + 1, 1); 39 for( ; R > r; R--) update(R, -1); 40 p[i].ans = ans; 41 } 42 sort(p + 1, p + 1 + m, cmpid); 43 for(int i = 1; i <= m; i++) printf("%d\n", p[i].ans); 44 } 45 return 0; 46 } 47 /* 48 6 49 1 2 3 4 3 5 50 4 51 1 2 52 3 5 53 2 6 54 1 1 55 */