zoukankan      html  css  js  c++  java
  • 【BZOJ3809】Gty的二逼妹子序列

    3809: Gty的二逼妹子序列

    Time Limit: 80 Sec  Memory Limit: 28 MB
    Submit: 1627  Solved: 481
    [Submit][Status][Discuss]

    Description

    Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题。
     
    对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数。
     
    为了方便,我们规定妹子们的美丽度全都在[1,n]中。
     
    给定一个长度为n(1<=n<=100000)的正整数序列s(1<=si<=n),对于m(1<=m<=1000000)次询问“l,r,a,b”,每次输出sl...sr中,权值∈[a,b]的权值的种类数。

    Input

    第一行包括两个整数n,m(1<=n<=100000,1<=m<=1000000),表示数列s中的元素数和询问数。
     
    第二行包括n个整数s1...sn(1<=si<=n)。
     
    接下来m行,每行包括4个整数l,r,a,b(1<=l<=r<=n,1<=a<=b<=n),意义见题目描述。
     
    保证涉及的所有数在C++的int内。
     
    保证输入合法。

    Output

    对每个询问,单独输出一行,表示sl...sr中权值∈[a,b]的权值的种类数。

    Sample Input

    10 10
    4 4 5 1 4 1 5 1 2 1
    5 9 1 2
    3 4 7 9
    4 4 2 5
    2 3 4 7
    5 10 4 4
    3 9 1 1
    1 4 5 9
    8 9 3 3
    2 2 1 6
    8 9 1 4

    Sample Output

    2
    0
    0
    2
    1
    1
    1
    0
    1
    2

    HINT

    样例的部分解释:

     

    5 9 1 2

    子序列为4 1 5 1 2

    在[1,2]里的权值有1,1,2,有2种,因此答案为2。

     

    3 4 7 9

    子序列为5 1

    在[7,9]里的权值有5,有1种,因此答案为1。

     

    4 4 2 5

    子序列为1

    没有权值在[2,5]中的,因此答案为0。

     

    2 3 4 7

    子序列为4 5

    权值在[4,7]中的有4,5,因此答案为2。

     

    建议使用输入/输出优化。

    Source

    分块+莫队

    我们用一个cnt[j]表示第i个询问时j出现次数

    我们维护每个块中有多少个元素(第一次?第一次被查询+第一次出现过),我们只要用val数组记录一下某个块有多少个数被维护

    假设我们某一次询问移动l,r导致其减成0,我们就更新答案

    具体来说我也不是很懂 %一发Flere825

    /*To The End Of The Galaxy*/
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<iomanip>
    #include<stack>
    #include<map>
    #include<set>
    #include<cmath>
    #include<complex>
    #define debug(x) cerr<<#x<<"="<<x<<endl
    #define INF 0x7f7f7f7f
    #define llINF 0x7fffffffffffll
    using namespace std;
    typedef pair<int,int> pii;
    typedef long long ll;
    inline int init()
    {
        int now=0,ju=1;char c;bool flag=false;
        while(1)
        {
            c=getchar();
            if(c=='-')ju=-1;
            else if(c>='0'&&c<='9')
            {
                now=now*10+c-'0';
                flag=true;
            }
            else if(flag)return now*ju;
        }
    }
    inline long long llinit()
    {
        long long now=0,ju=1;char c;bool flag=false;
        while(1)
        {
            c=getchar();
            if(c=='-')ju=-1;
            else if(c>='0'&&c<='9')
            {
                now=now*10+c-'0';
                flag=true;
            }
            else if(flag)return now*ju;
        }
    }
    struct node
    {
        int l,r,a,b,id,ans;
    }query[1000101];
    int n,m;
    int bel[100001];
    int block,divi;
    int ans;
    #define pos(x) (((x-1)/block)+1)
    bool cmp(node a,node b)
    {
        if(pos(a.l)!=pos(b.l))
        {
            return pos(a.l)<pos(b.l);
        }
        else return a.r<b.r;
    }
    bool cmpid(node a,node b)
    {
        return a.id<b.id;
    }
    int cnt[100005],val[100005];
    int a[100005];
    inline void Plus(int p)
    {
        cnt[a[p]]++;
        if(cnt[a[p]]==1)val[bel[a[p]]]++;
    }
    inline void Minus(int p)
    {
        cnt[a[p]]--;
        if(cnt[a[p]]==0)val[bel[a[p]]]--;
    }
    inline int ask(int l,int r)
    {
        int ans=0;
        if(bel[l]==bel[r])
        {
            for(int i=l;i<=r;i++)
            {
                if(cnt[i])ans++;
            }
            return ans;
        }
        for(int i=l;i<=bel[l]*divi;i++)
        {
            if(cnt[i])
            {
                ans++;
            }
        }
        for(int i=((bel[r]-1)*divi)+1;i<=r;i++)
        {
            if(cnt[i])
            {
                ans++;
            }
        }
        for(int i=bel[l]+1;i<bel[r];i++)
        {
            ans+=val[i];
        }
        return ans;
    }
    int main()
    {
        int l=1,r=0;
        n=init();m=init();
        block=sqrt(m);
        divi=sqrt(n);
        for(int i=1;i<=n;i++)
        {
            a[i]=init();
            bel[i]=((i-1)/divi)+1;
        }
        for(int i=1;i<=m;i++)
        {
            query[i].l=init();query[i].r=init();query[i].a=init();query[i].b=init();
            query[i].id=i;
        }
        sort(query+1,query+1+m,cmp);
        for(int i=1;i<=m;i++)
        {
            if(query[i].r>r)
            {
                for(r=r+1;r<=query[i].r;r++)
                {
                    Plus(r);
                }
            }
            else if(query[i].r<r)
            {
                for(;r>query[i].r;r--)
                {
                    Minus(r);
                }
            }
            if(query[i].l>l)
            {
                for(;l<query[i].l;l++)
                {
                    Minus(l);
                }
            }
            else if(query[i].l<l)
            {
                for(l=l-1;l>=query[i].l;l--)
                {
                    Plus(l);
                }
            }
            l=query[i].l;r=query[i].r;
            query[i].ans=ask(query[i].a,query[i].b);
        }
        sort(query+1,query+1+m,cmpid);
        for(int i=1;i<=m;i++)
        {
            printf("%d
    ",query[i].ans);
        }
        return 0;
    }
    /*
    srO xudyh davidlee1999WTK linkct1999 Orz
    compiler TDM-GCC 5.9.2
    */
    View Code
  • 相关阅读:
    CriminalIntent项目开发笔记(二)
    CriminalIntent项目开发笔记(一)----动态添加Fragment
    android应用中去掉标题栏的方法
    15个IT程序员必须思考的问题
    Android Studio快捷键
    Android 学习笔记
    win7系统安装方法
    jquery随学随记
    接口功能测试策略--转载
    测试随笔
  • 原文地址:https://www.cnblogs.com/redwind/p/6501928.html
Copyright © 2011-2022 走看看