zoukankan      html  css  js  c++  java
  • 2018牛客网暑期ACM多校训练营(第一场) J

    题目链接:https://www.nowcoder.com/acm/contest/139/J

    题目描述 

    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 a1, a2, ..., an.
    The i-th of the following q lines contains two integers li and ri.

    输出描述:

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

    输入

    3 2
    1 2 1
    1 2
    1 3
    4 1
    1 2 3 4
    1 3

    输出

    2
    1
    3

    备注:

    * 1 ≤ n, q ≤ 105
    * 1 ≤ ai ≤ n
    * 1 ≤ li, ri ≤ n
    * The number of test cases does not exceed 10.

    题意:

    给出序列a[1:n],给出q个查询,每个查询包含(l,r),要求回答a[1:l]和a[r:n]合起来有多少不同的整数。

    题解:

    莫队算法。

    统计a[1:n]有多少不同的整数,记为sum,所有 r - l ≤ 1 的查询答案为sum,

    cnt[k]表示整数k出现了几次,sum的变动根据cnt[k]的0→1以及1→0变化判断。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=1e5+10;
    const int MAXQ=1e5+10;
     
    struct Query
    {
        int block;
        int id;
        int l,r;
        bool operator <(const Query &oth) const
        {
            return (this->block == oth.block) ? (this->r < oth.r) : (this->block < oth.block);
        }
    }query[MAXQ];
     
    int n,q;
    int sum;
    int num[MAXN],cnt[MAXN];
    int ans[MAXQ];
     
    int main()
    {
        while(scanf("%d%d",&n,&q)!=EOF)
        {
            memset(cnt,0,sizeof(cnt));
            sum=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&num[i]);
                if(cnt[num[i]]==0) sum++;
                cnt[num[i]]++;
            }
     
            int len=sqrt(n);
            for(int i=1;i<=q;i++)
            {
                scanf("%d%d",&query[i].l,&query[i].r);
                if(query[i].r-query[i].l<=1) ans[i]=sum;
                query[i].block=query[i].l/len;
                query[i].id=i;
            }
            sort(query+1,query+q+1);
     
            int pl=1,pr=2;
            for(int i=1;i<=q;i++)
            {
                if(query[i].r-query[i].l<=1) continue;
     
                if(pr<query[i].r)
                {
                    for(int j=pr;j<query[i].r;j++)
                    {
                        cnt[num[j]]--;
                        if(cnt[num[j]]==0) sum--;
                    }
                }
                if(pr>query[i].r)
                {
                    for(int j=pr-1;j>=query[i].r;j--)
                    {
                        if(cnt[num[j]]==0) sum++;
                        cnt[num[j]]++;
                    }
                }
                if(pl<query[i].l)
                {
                    for(int j=pl+1;j<=query[i].l;j++)
                    {
                        if(cnt[num[j]]==0) sum++;
                        cnt[num[j]]++;
                    }
                }
                if(pl>query[i].l)
                {
                    for(int j=pl;j>query[i].l;j--)
                    {
                        cnt[num[j]]--;
                        if(cnt[num[j]]==0) sum--;
                    }
                }
     
                ans[query[i].id]=sum;
     
                pl=query[i].l;
                pr=query[i].r;
            }
     
            for(int i=1;i<=q;i++)
            {
                printf("%d
    ",ans[i]);
            }
        }
    }
  • 相关阅读:
    Mac上搭建Web服务器
    从零开始学ios开发(三):第一个有交互的app
    从零开始学ios开发(二):Hello World!
    C#核心语法
    WP8的新功能-通过一个程序来启动另一个程序
    .NET Web开发技术简单整理
    windows phone 下拉刷新
    使用X.509数字证书加密解密实务(一)-- 证书的获得和管理
    使用X.509数字证书加密解密实务(三)-- 使用RSA证书结合对称加密技术加密长数据
    使用X.509数字证书加密解密实务(二)-- 使用RSA证书加密敏感数据
  • 原文地址:https://www.cnblogs.com/dilthey/p/9341313.html
Copyright © 2011-2022 走看看