bzoj4216 -- 分块

如果没有内存限制,显然树状数组就可以了。

有了内存限制,我们使用分块。

因为没有修改操作,所以可以每16个数分一个块。

时间复杂度O(16*n)

注意不要用using namespace std,会占用1M不到的内存

 

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #define ll long long
 6 #define N 500001
 7 #define M 31251
 8 inline void Read(int& x){
 9     char c=getchar(),b=1;
10     for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
11     for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=getchar());x*=b;
12 }
13 inline void Read(bool& x){
14     char c=getchar();
15     for(;c<'0'||c>'9';c=getchar());
16     for(x=0;c>='0'&&c<='1';x=c-48,c=getchar());
17 }
18 char ss[30];
19 int Len;
20 inline void Print(ll x){
21     if(x<0)putchar('-'),x=-x;
22     if(x==0)putchar(48);
23     for(Len=0;x;x/=10)ss[++Len]=x%10;
24     while(Len)putchar(ss[Len--]+48);putchar('\n');
25 }
26 ll Sum[M],Ans;
27 int a[N],Cnt,s,n,m,x,y,i,t;
28 bool f;
29 inline void Query(int l,int r){
30     if(l>>4>=(r>>4)-1){
31         for(;l<=r;l++)Ans+=a[l];
32         return;
33     }
34     Ans+=Sum[(r>>4)-1]-Sum[l>>4];
35     for(i=l;i>>4==l>>4&&i<=n;i++)Ans+=a[i];
36     for(i=r;i>>4==r>>4&&i;i--)Ans+=a[i];
37 }
38 int main(){
39     Read(n);Read(m);Read(f);
40     for(i=1;i<=n;i++)Read(a[i]),Sum[i>>4]+=a[i];
41     for(i=1;i<=n>>4;i++)Sum[i]+=Sum[i-1];
42     while(m--){
43         Read(x);Read(y);
44         if(f){
45             if(Ans<0)Ans=-Ans;
46             x=(Ans^x)%n+1;y=(Ans^y)%n+1;
47             if(x>y)t=x,x=y,y=t;
48         }
49         Ans=0;Query(x,y);
50         Print(Ans);
51     }
52     return 0;
53 }
bzoj4216

 

posted @ 2017-04-19 09:14  gjghfd  阅读(153)  评论(0编辑  收藏  举报