题目链接:https://www.nowcoder.com/acm/contest/139/J
题目:
题意:给你n个数,q次查询,对于每次查询得l,r,求1~l和r~n元素得种类。
莫队思路:1.将元素copy一份到最右边然后对于每次查询得l,r,我们就可以转换成求r,l+n这一个连续区间得元素种类,就将其转换成了一个莫队模板题了(比赛时还不会莫队就随便找了个板子);
2.将移动的两个指针l设为0,r设为n+1,然后进行莫队即可。
做法一代码实现如下:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstdlib> 6 #include <cstring> 7 #include <vector> 8 #include <list> 9 #include <map> 10 #include <stack> 11 #include <queue> 12 using namespace std; 13 #define ll long long 14 const int maxn1 = 200005; 15 int cur[maxn1]; 16 int then[maxn1]; 17 int ans[maxn1]; 18 int limit,n,m; 19 struct node 20 { 21 int l,r,id; 22 }que[maxn1]; 23 bool cmp(node x,node y) 24 { 25 if(x.l/limit == y.l/limit) 26 return x.r < y.r; 27 return x.l/limit < y.l/limit; 28 } 29 void init() 30 { 31 for(int i = 1;i <= n;i++) { 32 scanf("%d",&cur[i]); 33 cur[i+n] = cur[i]; 34 } 35 for(int i = 1;i <= m;i++) 36 { 37 scanf("%d%d",&que[i].l,&que[i].r); 38 int t = que[i].r; 39 que[i].r = que[i].l + n; 40 que[i].l = t; 41 que[i].id = i; 42 } 43 limit = (int)(sqrt(2 * n)+0.5); 44 memset(then,0,sizeof(then)); 45 memset(ans, 0, sizeof(ans)); 46 sort(que+1,que+1+m,cmp); 47 } 48 void solve() 49 { 50 int L,R,ans1; 51 L = R = 0; 52 ans1 = 0; 53 for(int i = 1;i <= m;i++) 54 { 55 while(que[i].l > L) 56 { 57 then[cur[L]]--; 58 if(then[cur[L]] == 0) 59 ans1--; 60 L++; 61 } 62 while(que[i].r < R) 63 { 64 then[cur[R]]--; 65 if(then[cur[R]] == 0) 66 ans1--; 67 R--; 68 } 69 while(que[i].l < L) 70 { 71 L--; 72 then[cur[L]]++; 73 if(then[cur[L]] == 1) 74 ans1++; 75 } 76 while(que[i].r > R) 77 { 78 R++; 79 then[cur[R]]++; 80 if(then[cur[R]] == 1) 81 ans1++; 82 } 83 ans[que[i].id] = ans1; 84 } 85 for(int i = 1;i <= m;i++) 86 printf("%d\n",ans[i]); 87 } 88 int main() 89 { 90 while(~scanf("%d%d", &n, &m)) { 91 init(); 92 solve(); 93 } 94 return 0; 95 }
做法二代码实现如下:
1 #include <set> 2 #include <map> 3 #include <queue> 4 #include <stack> 5 #include <cmath> 6 #include <bitset> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 typedef long long ll; 17 typedef unsigned long long ull; 18 19 #define bug printf("*********\n"); 20 #define FIN freopen("in.txt", "r", stdin); 21 #define debug(x) cout<<"["<<x<<"]" <<endl; 22 #define IO ios::sync_with_stdio(false),cin.tie(0); 23 24 const double eps = 1e-8; 25 const int mod = 1e9 + 7; 26 const int maxn = 1e5 + 7; 27 const double pi = acos(-1); 28 const int inf = 0x3f3f3f3f; 29 const ll INF = 0x3f3f3f3f3f3f3f3f; 30 31 inline int read() {//读入挂 32 int ret = 0, c, f = 1; 33 for(c = getchar(); !(isdigit(c) || c == ‘-‘); c = getchar()); 34 if(c == ‘-‘) f = -1, c = getchar(); 35 for(; isdigit(c); c = getchar()) ret = ret * 10 + c - ‘0‘; 36 if(f < 0) ret = -ret; 37 return ret; 38 } 39 40 int n, q, sum, block; 41 int a[maxn], cnt[maxn], pos[maxn]; 42 43 struct node { 44 int l, r, ans, id; 45 }ask[maxn]; 46 47 bool cmp(const node& x, const node& y) { 48 return pos[x.l] == pos[y.l] ? x.r < y.r : x.l < y.l; 49 } 50 51 void add(int x) { 52 cnt[x]++; 53 if(cnt[x] == 1) sum++; 54 } 55 56 void del(int x) { 57 if(cnt[x] == 1) sum--; 58 cnt[x]--; 59 } 60 61 int main() { 62 //FIN; 63 while(~scanf("%d%d", &n, &q)) { 64 for(int i = 1; i <= n; i++) { 65 cnt[i] = 0; 66 } 67 sum = 0; 68 block = sqrt(2 * n); 69 for(int i = 1; i <= n; i++) { 70 a[i] = read(); 71 pos[i] = (i - 1) / block; 72 } 73 for(int i = 1; i <= q; i++) { 74 ask[i].l = read(); 75 ask[i].r = read(); 76 ask[i].id = i; 77 } 78 sort(ask + 1, ask + q + 1, cmp); 79 for(int i = 1, l = 0, r = n + 1; i <= q; i++) { 80 while(r < ask[i].r) del(a[r++]); 81 while(r > ask[i].r) add(a[--r]); 82 while(l < ask[i].l) add(a[++l]); 83 while(l > ask[i].l) del(a[l--]); 84 ask[ask[i].id].ans = sum; 85 } 86 for(int i = 1; i <= q; i++) 87 printf("%d\n", ask[i].ans); 88 } 89 return 0; 90 }
Different Integers(牛客多校第一场+莫队做法)
原文:https://www.cnblogs.com/Dillonh/p/9374633.html