• 牛客网暑期ACM多校训练营(第一场)


    链接:https://www.nowcoder.com/acm/contest/139/J
    来源:牛客网

    时间限制:C/C++ 2秒,其他语言4秒
    空间限制:C/C++ 524288K,其他语言1048576K
    64bit IO Format: %lld

    题目描述

    Given a sequence of integers a1, a2, ..., an and q pairs of integers (l1, r1), (l2, r2), ..., (lq, rq), find count(l1, r1), count(l2, r2), ..., count(lq, rq) where count(i, j) is the number of different integers among a1, a2, ..., ai, aj, aj + 1, ..., an.

    输入描述:

    The input consists of several test cases and is terminated by end-of-file.
    The first line of each test cases contains two integers n and q.
    The second line contains n integers a
    1
    , a
    2
    , ..., a
    n
    .
    The i-th of the following q lines contains two integers l
    i
     and r
    i
    .

    输出描述:

    For each test case, print q integers which denote the result.
    示例1

    输入

    复制
    3 2
    1 2 1
    1 2
    1 3
    4 1
    1 2 3 4
    1 3

    输出

    复制
    2
    1
    3

    备注:

    * 1 ≤ n, q ≤ 10
    5

    * 1 ≤ a
    i
     ≤ n
    * 1 ≤ l
    i
    , r
    i
     ≤ n
    * The number of test cases does not exceed 10.


    骚操作:直接把数组*2 然后求1-L,R-N 就变成 求R-L+N之间的不同数的个数了;注意,主席树会TLE;要用线段数组+离线

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <map>
     
    using namespace std;
    const int maxn=300000+5;
    map<int,int> mp;
    int data[maxn];
    int a[maxn];
    int ans[200000+5];
    struct node{
        int l,r,id;
        bool operator<(node t)const{
            return r<t.r;
        }
    }q[200000+5];
    int sum(int i){
        int ans=0;
        while(i>0){
            ans+=data[i];
            i-=i&-i;
        }
        return ans;
    }
    void add(int i,int x){
        while(i<maxn){
            data[i]+=x;
            i+=i&-i;
        }
    }
     
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m)){
            fill(data,data+n*2+2,0);
            mp.clear();
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                a[i+n]=a[i];
            }
            n=n*2;
     
     
            for(int i=0;i<m;i++){
                int x,y;
                scanf("%d%d",&x,&y);
                q[i].l=y;
                q[i].r=x+n/2;
                q[i].id=i;
            }
            sort(q,q+m);
            int pre=1;
            for(int i=0;i<m;i++){
                for(int j=pre;j<=q[i].r;j++){
                    if(mp[a[j]]!=0){
                        add(mp[a[j]],-1);
                    }
                    add(j,1);
                    mp[a[j]]=j;
                }
                pre=q[i].r+1;
                ans[q[i].id]=sum(q[i].r)-sum(q[i].l-1);
            }
            for(int i=0;i<m;i++){
                printf("%d
    ",ans[i]);
            }
        }
        return 0;
    }

    也可以莫队加上读入挂

    #include<bits/stdc++.h>
     
    using namespace std;
    int n,q,a[100005];
    int L,R,ans;
    struct node{
        int l,r,id;
    };
    node temp[100005];
    int sum[1000005];
    int anw[1000005];
    int block[100005];
    int read()
    {
        char ch=' ';
        int ans=0;
        while(ch<'0' || ch>'9')
            ch=getchar();
        while(ch<='9' && ch>='0')
        {
            ans=ans*10+ch-'0';
            ch=getchar();
        }
        return ans;
    }
    int cmp(node a,node b){
        if(block[a.l]==block[b.l])return block[a.r]<block[b.r];
        return block[a.l]<block[b.l];
    }
    void add(int x){
        if(sum[x]==0)ans++;sum[x]++;
    }
    void del(int x){
        sum[x]--;if(sum[x]==0)ans--;
    }
    int main()
    {
     
        ios::sync_with_stdio(false);
        while(~scanf("%d%d",&n,&q)){
            memset(sum,0,sizeof(sum));
            for(int i=1;i<=n;i++){
                a[i]=read();
                block[i]=i/sqrt(n);
            }
            for(int i=1;i<=q;i++){
                temp[i].l=read();
                temp[i].r=read();
                temp[i].id=i;
            }
            sort(temp+1,temp+1+q,cmp);
            L=0;R=n+1;ans=0;
            for(int i=1;i<=q;i++){
                while(L<temp[i].l)L++,add(a[L]);
                while(R>temp[i].r)R--,add(a[R]);
                while(L>temp[i].l)del(a[L]),L--;
                while(R<temp[i].r)del(a[R]),R++;
                anw[temp[i].id]=ans;
            }
            for(int i=1;i<=q;i++)printf("%d
    ",anw[i]);
     
        }
        return 0;
    }
  • 相关阅读:
    BZOJ4066 简单题(KD-Tree)
    [HAOI2006]受欢迎的牛 tarjan缩点 + 拓扑排序
    [JSOI2007]重要的城市 floyd:最短路计数
    [SDOI2017]新生舞会 0/1分数规划
    [APIO2017]商旅 0/1分数规划
    [HNOI2009]最小圈
    算法——0/1分数规划
    运动员最佳匹配问题 KM算法:带权二分图匹配
    [NOI2015]荷马史诗
    [HAOI2010]计数 数位DP+组合数
  • 原文地址:https://www.cnblogs.com/luowentao/p/9338237.html
Copyright © 2020-2023  润新知