BZOJ 4216 Pig 分块乱搞

题意:链接

方法:分块以节约空间。

解析:

这题坑的地方就是他只有3M的内存限制,如果我们开longlong前缀和是必死的。

所以考虑缩小这个long long数组的大小。

然后想到分块

不妨以15为大小进行分块,其实不T再大一点也行,但是算内存的话15是差不多的吧。

然后记录每个块内的和,然后询问的时候整块直接拿,非整块暴力枚举,顶多30个点。

所以时间上能过,然后内存上也就2.6MB左右,可以过。

但是有个问题啊,千万别打using namespace std;

这个运行自动申请700kb内存,太坑辣!

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 500005
#define M 33335
#define K 16
typedef long long ll;
int a[N];
ll sum[M];
int n,m,jd,blockl,blockr,cntblock,l,r;
ll ans;
void calc(int l,int r)
{
    blockl=l>>4;
    blockr=r>>4;
    ans+=sum[blockr-1]-sum[blockl];
    for(int i=l;i>>4==blockl&&i>0&&i<=n;i++)
    {
        ans+=a[i];
    }
    for(int i=r;i>>4==blockr&&i>0&&i<=n;i--)
    {
        ans+=a[i];
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&jd);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        sum[i>>4]+=a[i];
    }
    cntblock=n>>4;
    for(int i=1;i<=cntblock;i++)sum[i]+=sum[i-1];
    for(int i=1;i<=m;i++)
    {
        if(ans<0)ans=-ans;
        scanf("%d%d",&l,&r);
        if(jd)
        {
            l=(l^ans)%n+1;
            r=(r^ans)%n+1;
            if(l>r)
                l^=r^=l^=r;
        }
        ans=0;calc(l,r);
        printf("%lld\n",ans);
    }
}

你可能感兴趣的:(pig,内存)