• 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
    ",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("*********
    ");
    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
    ", ask[i].ans);
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    转:中国菜刀用法
    转的:burp suite小例子
    [转]阿里前员工评马云
    Burp Suite使用教程
    C++实现按绩点排名
    C++排列对称串
    C++实现01串排序
    C++判断五位以内的对称素数
    C++12!配对
    C++列出完数
  • 原文地址:https://www.cnblogs.com/Dillonh/p/9374633.html
Copyright © 2020-2023  润新知