zoukankan      html  css  js  c++  java
  • NBUT

    题目链接:https://vjudge.net/problem/38739/origin

    题目表述:

    Sona , Maven of the Strings . Of cause, she can play the zither. Sona can't speak but she can make fancy music. Her music can attack, heal, encourage and enchant.There're an ancient score(乐谱). But because it's too long,Sona can't play it in a short moment. So Sona decide to just play a part of it and revise it. A score is composed of notes. There are 109 kinds of notes and a score has 105 notes at most.To diversify Sona's own score, she have to select several parts of it. The energy of each part is calculated like that:Count the number of times that each notes appear. Sum each of the number of times' cube together. And the sum is the energy.You should help Sona to calculate out the energy of each part.

    Input

    This problem contains several cases. And this problem provides 2 seconds to run. 
    The first line of each case is an integer N (1 ≤ N ≤ 10^5), indicates the number of notes. 
    Then N numbers followed. Each number is a kind of note. (1 ≤ NOTE ≤ 10^9) 
    Next line is an integer Q (1 ≤ Q ≤ 10^5), indicates the number of parts. 
    Next Q parts followed. Each part contains 2 integers Li and Ri, indicates the left side of the part and the right side of the part.

    Output

    For each part, you should output the energy of that part.

    Sample Input

    8
    1 1 3 1 3 1 3 3
    4
    1 8
    3 8
    5 6
    5 5

    Sample Output

    128
    72
    2
    1

    题目大意:

    右N个数字,M个询问,求每个询问区间[L,R]中,每种数字出现次数的立方和

    分析:用莫队算法能够很好处理该题,将原数组离散化后(离散化的过程小总结),能够用数组cnt记录区间中每个数字出现的次数,若此时统计的区间为[L,R],用ans保存区间的答案,若区间需要增加一个元素a,ans-=cnt[a[n]]后,cnt[a[n]]++(a的个数增加1),ans+=cnt[a[n]]3 ,若区间需要减少一个元素a,则ans-=cnt[a[n]]3 ,后cnt[a[n]]--(a的个数减1),ans+=cnt[a[n]]3 即可.

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int MAX=1e5+10;
    typedef long long ll;    
    inline int read()                        //输入优化 
    {
        char c=getchar();
        int x=0,f=1;
        while(c<'0'||c>'9')
        {if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9')
        {x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int N,M,size,l,r;
    int a[MAX],cnt[MAX],temp[MAX];        //a数组为原数组值,cnt为记录区间数字个数的数组,temp离散化时拷贝数组 
    ll ans[MAX],ANS;                    //记录答案 
    struct Query
    {
        int L,R,ID,block;    
        Query(){}
        Query(int l,int r,int id):L(l),R(r),ID(id)
        {
            block=l/size;                                //分块 
        }             
        bool operator < (const Query rhs)const            //重载<运算符,莫队的排序 
        {
            if(block==rhs.block)return R<rhs.R;
            return block<rhs.block;
        }
    }queries[MAX];
    ll cube(ll a)                     
    {    
        return a*a*a;
    }
    void insert(int n)
    {
        ANS-=cube(cnt[a[n]]);
        cnt[a[n]]++;
        ANS+=cube(cnt[a[n]]);
    }
    void erase(int n)
    {
        ANS-=cube(cnt[a[n]]);
        cnt[a[n]]--;
        ANS+=cube(cnt[a[n]]);
    }
    int main()
    {
        while(scanf("%d",&N)!=EOF)
        {
            ANS=0;                                    //初始化 
            memset(a,0,sizeof(a));
            memset(temp,0,sizeof(temp));
            memset(cnt,0,sizeof(cnt));
            memset(ans,0,sizeof(ans));
            
            size=sqrt(N+0.5);                                    //离散化 
            for(int i=1;i<=N;i++)    
                a[i]=read(),temp[i]=a[i];
            sort(temp+1,temp+1+N);
            int sum=unique(temp+1,temp+1+N)-temp-1;
            for(int i=1;i<=N;i++)
            {
                a[i]=lower_bound(temp+1,temp+1+sum,a[i])-temp;
            }
            
            M=read();    
            for(int i=1;i<=M;i++)                        //输入询问 
            {
                l=read(),r=read();
                queries[i]=Query(l,r,i);
            }
            sort(queries+1,queries+1+M);                //莫队排序 
            int L=1,R=0;
            for(int i=1;i<=M;i++)                        //莫队算法 
            {
                while(L>queries[i].L)insert(--L);
                while(L<queries[i].L)erase(L++);
                while(R>queries[i].R)erase(R--);
                while(R<queries[i].R)insert(++R);
                
                ans[queries[i].ID]=ANS;
            }
            for(int i=1;i<=M;i++)
                printf("%I64d
    ",ans[i]);    
        }
        return 0;
    }
  • 相关阅读:
    Linux 服务器连接远程数据库(Mysql、Pgsql)
    oracle主键自增
    全排列算法实现
    python动态导入包
    python发红包实现
    CentOS 6.8安装Oracle 11 g 解决xhost: unable to open display
    xargs的一个小坑
    利用ssh-copy-id复制公钥到多台服务器
    redhat 5 更换yum源
    【原创】Hadoop的IO模型(数据序列化,文件压缩)
  • 原文地址:https://www.cnblogs.com/LjwCarrot/p/9048357.html
Copyright © 2011-2022 走看看