bzoj4216 Pig
水题,题目难点大概就是空间限制上了,开longlong会爆,可以开个int数组求前缀和,然后一旦绝对值超过20亿,则将其取模,并记录下当前位置,这样询问时就可以二分这些超过的位置,将其乘以20亿后加上前缀和就是答案。
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<set> 4 #define N 500010 5 using namespace std; 6 int n,m,t,i,a,b; 7 int s[N],v[20010],w[20010],tot; 8 long long ans; 9 long long ef(int x) 10 { 11 int l,r,m; 12 l=1;r=tot; 13 while (l<=r) 14 { 15 m=(l+r)>>1; 16 if (v[m]<=x) l=m+1;else r=m-1; 17 } 18 return w[r]; 19 } 20 int main() 21 { 22 scanf("%d%d%d",&n,&m,&t); 23 for (i=1;i<=n;i++) 24 { 25 scanf("%d",&s[i]); 26 s[i]+=s[i-1]; 27 if (s[i]>=2000000000) 28 { 29 s[i]%=2000000000; 30 tot++;v[tot]=i;w[tot]=1; 31 } 32 else 33 if (s[i]<=-2000000000) 34 { 35 s[i]%=2000000000; 36 tot++;v[tot]=i;w[tot]=-1; 37 } 38 } 39 for (i=1;i<=tot;i++) 40 w[i]+=w[i-1]; 41 for (i=1;i<=m;i++) 42 { 43 scanf("%d%d",&a,&b); 44 if (t==1) 45 { 46 a=(a^abs(ans))%n+1; 47 b=(b^abs(ans))%n+1; 48 } 49 if (a>b) 50 { 51 int t=a;a=b;b=t; 52 } 53 ans=(long long)2000000000*(ef(b)-ef(a-1))+s[b]-s[a-1]; 54 printf("%lld\n",ans); 55 } 56 }