• NBUT 1457 Sona (莫队算法)


    题目大意:

    求一段区间内 出现的数字的次数的三次方的和


    思路分析:

    这要水过去的题目真是难,各种优化。

    不能用map , 要离散化之后 先处理lowerbound。

    优化输入。

    时间卡的非常紧。

    题目直接用莫队水过去。

    假设你超时的话,最好还是试试上面三种优化。


    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <cmath>
    #define maxn 100005
    
    using namespace std;
    typedef long long LL;
    
    int app[maxn];
    int pos[maxn];
    int save[maxn];
    int x[maxn];
    
    map<int,int>mymap;
    
    struct foo
    {
        int l,r,index;
        LL ans;
        bool operator < (const foo &cmp) const
        {
            if(pos[l]==pos[cmp.l])return r<cmp.r;
            return pos[l]<pos[cmp.l];
        }
    }Q[maxn];
    int n;
    inline void scanf_(int &num){
        char in;
        bool neg=false;
        while(((in=getchar()) > '9' || in<'0') && in!='-') ;
        if(in=='-'){
            neg=true;
            while((in=getchar()) >'9' || in<'0');
        }
        num=in-'0';
        while(in=getchar(),in>='0'&&in<='9')
            num*=10,num+=in-'0';
        if(neg)
            num=0-num;
    }
    
    bool cmp_id(const foo &a,const foo &b)
    {
        return a.index<b.index;
    }
    int sz;
    void modify(int p,LL &ans,int add)
    {
        ans-=(LL)app[x[p]]*app[x[p]]*app[x[p]];
        app[x[p]]+=add;
        ans+=(LL)app[x[p]]*app[x[p]]*app[x[p]];
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            memset(app,0,sizeof app);
    
            int SIZE = (int)sqrt(n*1.0);
    
            for(int i=1;i<=n;i++)
            {
                scanf_(save[i]);
                x[i]=save[i];
                pos[i]=(i-1)/SIZE+1;
            }
            int m;
            scanf_(m);
            for(int i=0;i<m;i++)
            {
                scanf_(Q[i].l);
                scanf_(Q[i].r);
                Q[i].index=i;
            }
    
            sort(save+1,save+n+1);
            sz=unique(save+1,save+n+1)-save;
    
            for(int i=1;i<=n;i++)
            {
                x[i] = lower_bound(save+1,save+sz,x[i])-save;
            }
            sort(Q,Q+m);
            LL ans=0;
            for(int i=0,l=1,r=0;i<m;i++)
            {
                if(r<Q[i].r)
                {
                    for(r=r+1;r<=Q[i].r;r++)
                        modify(r,ans,1);
                    r--;
                }
                if(r>Q[i].r)
                {
                    for(;r>Q[i].r;r--)
                    {
                        modify(r,ans,-1);
                    }
                }
                if(l<Q[i].l)
                {
                    for(;l<Q[i].l;l++)
                        modify(l,ans,-1);
                }
                if(l>Q[i].l)
                {
                    for(l=l-1;l>=Q[i].l;l--)
                        modify(l,ans,1);
                    l++;
                }
    
                if(Q[i].l==Q[i].r)
                {
                    Q[i].ans=1;
                    continue;
                }
    
                Q[i].ans=ans;
            }
    
            sort(Q,Q+m,cmp_id);
            for(int i=0;i<m;i++)
                printf("%I64d
    ",Q[i].ans);
        }
        return 0;
    }
    


  • 相关阅读:
    junit所需要的jar包
    【SSH学习笔记】用Struts2实现简单的用户登录
    HIbernate 一对多 多对多
    Hibernate 干货2
    Hibernate 干货
    hibernate学习笔记
    Hibernate 框架学习
    Class的isAssignableFrom方法
    dubbo源码分析1——SPI机制的概要介绍
    Dubbo简介
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6795394.html
Copyright © 2020-2023  润新知