zoukankan      html  css  js  c++  java
  • bzoj 3781: 小B的询问 分块

    3781: 小B的询问

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 196  Solved: 135
    [Submit][Status]

    Description

    小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。小B请你帮助他回答询问。

    Input

    第一行,三个整数N、M、K。
    第二行,N个整数,表示小B的序列。
    接下来的M行,每行两个整数L、R。

    Output

    M行,每行一个整数,其中第i行的整数表示第i个询问的答案。
     

    Sample Input

    6 4 3
    1 3 2 1 1 3
    1 4
    2 6
    3 5
    5 6

    Sample Output

    6
    9
    5
    2
     
     
      网上题解都说是莫队算法,但是当时脑子一抽写了个分块,然后就过了。。。
      询问离线,按照r值排序,对于出现个数大于sqrt(n)的直接暴力二分即可,而个数小于sqrt(n)的部分可以这样处理,由于1,4,9,16是数列1,3,5,7的前缀和,对于一个数字在pos出现,即在pos处+1,如果之前出现过,则在之前出现的位置都+2,统计区间和[l,r]即为当前询问答案,具体详见代码。
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    #define MAXN 50010
    #define MAXB 300
    typedef long long qword;
    inline qword sqr(int x)
    {
            return (qword)x*x;
    }
    int a[MAXN];
    int rcv[MAXN];
    int prv[MAXN];
    int tot[MAXN];
    int vec[MAXB][MAXN];
    int vpos[MAXN],topv=0;
    struct qur_t
    {
            int id,x,y;
            qword ans;
    }qur[MAXN];
    bool cmp_y(qur_t q1,qur_t q2)
    {
            return q1.y<q2.y;
    }
    bool cmp_id(qur_t q1,qur_t q2)
    {
            return q1.id<q2.id;
    }
    int tarr[MAXN];
    void Add_tarr(int pos,int v)
    {
            while (pos<MAXN)
            {
                    tarr[pos]+=v;
                    pos+=pos&(-pos);
            }
    }
    int Query_tarr(int pos)
    {
            int ret=0;
            while (pos)
            {
                    ret+=tarr[pos];
                    pos-=pos&(-pos);
            }
            return ret;
    }
    
    int main()
    {
        //    freopen("input.txt","r",stdin);
        //    freopen("ouput.txt","w",stdout);
            int x,y,z,n,m,t;
            scanf("%d%d%d",&n,&m,&t);
            for (int i=1;i<=n;i++)
                    scanf("%d",a+i);
            for (int i=1;i<=n;i++)
            {
                    prv[i]=rcv[a[i]];
                    rcv[a[i]]=i;
            }
            for (int i=1;i<=n;i++)
                    tot[a[i]]++;
            int bs=(int)sqrt(max(n,t))*2;
            for (int i=1;i<=t;i++)
                    if (tot[i]>=bs)
                            vpos[i]=++topv;
            for (int i=1;i<=n;i++)
                    if (vpos[a[i]])
                            vec[vpos[a[i]]][++vec[vpos[a[i]]][0]]=i;
            for (int i=1;i<=m;i++)
                    scanf("%d%d",&qur[i].x,&qur[i].y),qur[i].id=i;
            sort(qur+1,qur+m+1,cmp_y);
            int *it1,*it2;
            for (int i=1;i<=m;i++)
            {
                    for (int j=1;j<=topv;j++)
                    {
                            it1=lower_bound(&vec[j][1],&vec[j][vec[j][0]] + 1,qur[i].x);
                            it2=upper_bound(it1,&vec[j][vec[j][0]] + 1,qur[i].y);
                            it2--;
                            qur[i].ans+=sqr((int)(it2-it1+1));
                    }
            }
            int qnow=1;
            for (int i=1;i<=n;i++)
            {
                    if (!vpos[a[i]])
                    {
                            Add_tarr(i,1);
                            x=prv[i];
                            while (x)
                            {
                                    Add_tarr(x,2);
                                    x=prv[x];
                            }
                    }
                    while (qnow<=m && qur[qnow].y==i)
                    {
                            qur[qnow].ans+=Query_tarr(i)-Query_tarr(qur[qnow].x-1);
                            qnow++;
                    }
            }
            sort(qur+1,qur+m+1,cmp_id);
            for (int i=1;i<=m;i++)
            {
                    printf("%lld
    ",qur[i].ans);
            }
    }
     
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    牛客 小乐乐和25
    codeforces 1303 D 二进制瞎搞
    codeforces 1307 D 最短路bz+贪心
    codeforces 1316 C math
    codeforces 1328E LCA
    codeforces 1335 E2 思维
    codeforces 1335 E1 思维
    codeforces 1342 D 贪心+后缀和
    codeforces 1348D (思维+贪心)
    codeforces 1362 E 进制的性质
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4301040.html
Copyright © 2011-2022 走看看