Different Integers(牛客多校第一场+莫队做法)

题目链接: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 }

猜你喜欢

转载自www.cnblogs.com/Dillonh/p/9374633.html