题意:id=4216">链接
方法:分块以节约空间。
解析:
这题坑的地方就是他仅仅有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);
}
}
时间: 2024-12-15 15:17:35