• CodeForces220B


    题意

    给出一个长度为(n)的数组,(m)次询问。每一次询问给出两个数(l)(r),表示在区间([l,r])内,查询在给定区间内有多少个数字,该数字出现次

    数等于它本身。

    思路

    题目中的ai最大(10^9),而数组范围(10^5),所以如果数据大于(10^5)了,这个数就不可能为所求的(x)忽略这个数后就不用进行离散化了。

    数据过大,我们无法开这么大的数组,所以要对其进行离散化处理,所以可以想到用莫队算法来解决。

    AC代码

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<cmath>
    #include<iostream>
    using namespace std;
    #define inf 0x3f3f3f3f
    const int N=1e5+20;
    typedef long long ll;
    
    int n,q,sum,a[N],belong[N],ans[N],cnt[N];
    
    inline char gc() //用fread读入加快读入速度,比一般read读入要快
    {
        static char buf [100000],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    
    inline int  read()
    {
        static char c=gc();
        ll x=0,f=1;
        for(; c>'9'||c<'0'; c=gc()) if(c=='-') f=-1;
        for(; c<='9'&&c>='0'; c=gc()) x=(x<<3)+(x<<1)+c-'0';
        return x*f;
    }
    
    struct node
    {
        int l,r,id;
    //    bool operator < (const node &x) const
    //    {
    //        if(belong[l]==belong[x.l])
    //            return r<x.r;
    //        else
    //            return belong[l]<belong[x.l];
    //    }
    } x[N];
    
    bool cmp1(node a,node b)
    {
        if(belong[a.l]==belong[b.l])
            return a.r<b.r;
        else
           // return a.l<b.l;
            return belong[a.l]<belong[b.l];
    }
    void print(int x)
    {
        if(x<0)
        {
            putchar('-');//putchar比普通输出快
            x=-x;
        }
        if(x>=10)
            print(x/10);
        putchar(x%10+'0');
        printf("
    ");
    }
    
    void add(int x)
    {
        if(a[x]>n)
            return;
        if(cnt[a[x]]==a[x])
            sum--;
        cnt[a[x]]++;
        if(cnt[a[x]]==a[x])
            sum++;
    }
    
    void del(int x)
    {
        if(a[x]>n)
            return;
        if(cnt[a[x]]==a[x])
            sum--;
        cnt[a[x]]--;
        if(cnt[a[x]]==a[x])
            sum++;
    }
    
    int main()
    {
        // n=read();
        //q=read();
        scanf("%d %d",&n,&q);
        int block=sqrt(n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            //a[i]=read();
            belong[i]=i/block;
        }
        for(int i=1; i<=q; i++)
        {
            scanf("%d %d",&x[i].l,&x[i].r);
            // x[i].l=read();
            //x[i].r=read();
            x[i].id=i;//记录编号
        }
        sort(x+1,x+q+1,cmp1);
        memset(cnt,0,sizeof(cnt));
        int L=1,R=0;
        for(int i=1; i<=q; i++)
        {
            while(x[i].l>L)
                del(L++);
            while(L>x[i].l)
                add(--L);
            while(R<x[i].r)
                add(++R);
            while(R>x[i].r)
                del(R--);
            ans[x[i].id]=sum;
        }
        for(int i=1; i<=q; i++)
            //  print(ans[i]);
            printf("%d
    ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    批量转外部样式为行内样式
    AngularJS 笔记2
    windows特殊文件或文件夹
    zepto 入门
    js闭包
    AngularJS 笔记1
    sublime配置 sublimecondeintel 分号后不要提示
    sublime插件开发手记
    用flvplayer.swf在网页中播放视频(网页中flash视频播放的实现)
    无插件启动谷歌浏览器
  • 原文地址:https://www.cnblogs.com/OFSHK/p/13714249.html
Copyright © 2020-2023  润新知