1. 程式人生 > >Different Integers(牛客多校第一場+莫隊做法)

Different Integers(牛客多校第一場+莫隊做法)

tdi har lock def ack type void *** 種類

題目鏈接: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(牛客多校第一場+莫隊做法)