LOJ 6281 数列分块入门 5
自己写分块时总是对于一个块内的修改写错
wa了好几次
自我感觉对于块内修改的操作,再封装一个函数是很方便的
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using std::min;
const int maxn=50100;
struct node
{
int l;
int r;
int A,B;//A for zero , B for one
int size,tot;
};
node squ[maxn];
int belong[maxn],size;
long long base[maxn];
void init(int n)
{
size=floor(sqrt(n));
for(int i=1,k=1;i<=n;i+=size,k++)
{
squ[k].l=i;squ[k].r=min(n,i+size-1);
squ[k].A=0;squ[k].B=0;squ[k].tot=0;
squ[k].size=squ[k].r-squ[k].l+1;
for(int j=squ[k].l;j<=squ[k].r;j++)
{
belong[j]=k;
if(base[j]==0) ++squ[k].A;
if(base[j]==1) ++squ[k].B;
squ[k].tot+=base[j];
}
}
return ;
}
void modify(int l,int r)
{
if(squ[belong[l]].A+squ[belong[l]].B==squ[belong[l]].size) return ;
for(int i=l;i<=r;i++)
{
if(base[i]==1||base[i]==0) continue;
squ[belong[i]].tot-=base[i];
base[i]=floor(sqrt(base[i]));
squ[belong[i]].tot+=base[i];
if(base[i]==0) ++squ[belong[i]].A;
if(base[i]==1) ++squ[belong[i]].B;
}
return ;
}
void MODIFY(int l,int r)
{
if(belong[l]==belong[r]) { modify(l,r);return ;}
int begin=belong[l],end=belong[r];
if(squ[belong[l]].l!=l) modify(l,squ[belong[l]].r),++begin;
if(squ[belong[r]].r!=r) modify(squ[belong[r]].l,r),--end;
for(int i=begin;i<=end;i++) modify(squ[i].l,squ[i].r);
return ;
}
int check(int l,int r)
{
//if(squ[belong[l]].A+squ[belong[l]].B==squ[belong[l]].size) return squ[belong[l]].B;
int res=0;
for(int i=l;i<=r;i++) res+=base[i];
return res;
}
int CHECK(int l,int r)
{
if(belong[l]==belong[r]) return check(l,r);
int begin=belong[l],end=belong[r],res=0;
if(squ[belong[l]].l!=l) res+=check(l,squ[belong[l]].r),++begin;
if(squ[belong[r]].r!=r) res+=check(squ[belong[r]].l,r),--end;
for(int i=begin;i<=end;i++) res+=squ[i].tot;
return res;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&base[i]);
init(n);
for(int i=1,a,b,c,d;i<=n;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
if(a)
printf("%d\n",CHECK(b,c));
else
MODIFY(b,c);
}
return 0;
}