题目
红学姐和黄学长是好朋友。
有一天,黄学长想吃猪肉丸,于是他去找红学姐买猪。红学姐到她的猪圈中赶猪的
时候发现有许多猪逃离了她的猪圈。同时红学姐发现,一个名叫wwf的魔法猪藏在某
个猪圈中施法。然而wwf实在太巨了,红学姐并没有办法捉住它,只好向方老师求救。
为了确定wwf的位置,方老师向红学姐提出了m组询问,每次询问标号在区间[l,r]内
的猪圈剩余的猪的数量和,但红学姐不屑于做这些简单的问题,就把它们交给了你,同
时给了你一台内存较小的电脑。
由于wwf施展了一些奇怪的魔法,所以猪圈中猪的数量可能是负数。
分析
我居然在酒店刷题//丧心病狂//
扫了一遍题//居然没读懂,看了一波样例,没有问题,我知道他在说什么了,求个前缀和不就好了吗//但是//但是他只给3MB内存是什么鬼啊//
然后算了一波空间,发现似乎没什么大问题//但是,如果要long long的话不就炸了吗!!!
果断看题解//我们可以以15为大小来进行分块,对于一整块的,我们用前缀和来维护,直接拿就好,对于不是一整块的,我们暴力扫一遍就是了,然后这道题就被愉快的解决啦!
代码
#include <cstdio>
#define N 500005
#define M 33335
#define K 16
#define ll long long
int a[N];
ll sum[M];
ll ans;
int n,m,t;
int l,r;
int cntB,Bl,Br;
void cal(int l,int r)
{
Bl = l >> 4;
Br = r >> 4;
ans += sum[Br - 1] - sum[Bl];
for (int i = l; i >> 4 == Bl && i > 0 && i <= n; i++)
{
ans += a[i];
}
for (int i = r; i >> 4 == Br && i > 0 && i <= n; i--)
{
ans += a[i];
}
}
int main()
{
scanf("%d%d%d",&n,&m,&t);
for (int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
sum[i >> 4] += a[i];
}
cntB = n >> 4;
for (int i = 1; i <= cntB; i++)
sum[i] += sum[i -1];
for (int i = 1; i <= m; i++)
{
scanf("%d%d",&l,&r);
if (ans < 0) ans = -ans;
if (t)
{
l = (l ^ ans) % n + 1;
r = (r ^ ans) % n + 1;
if (l > r)
l ^= r ^= l ^= r;
}
ans = 0;
cal(l,r);
printf("%lld\n",ans);
}
}