- 为什么要写这个看上去很水的题的题解呢..因为它坑点太多了,我足足调了1个上午+1个晚上+一整天。
- 还是分块大法吼啊,分块大法保平安。
- 题意(原题):
- 数列区间加法,区间求%7=0的元素个数。
- 思路:
- 这题特别坑…主要的坑点在于它不像普通区间加法区间求和一样,区间加法只需要给自己加上特征值然后改一下lazy,它的更新是需要用到他的子节点的信息的,所以treeAdd的时候也要分发lazy,还有一大堆坑点都忘光了。。手造了n个错误数据,一个个调试修掉,然后还是wa,然后又对拍了n个错误数据全部改掉才ac,真的心累。
- 代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN (110000)
using namespace std;
struct node
{
int l,r,mid,ls,rs,lazy,val[7];
node()
{
l=r=mid=ls=rs=0;
memset(val,0,sizeof(val));
}
}a[MAXN*2];
char ss[11];
int n,m,len=0,readVal[MAXN];
void treeAddVal(int x,int val)
{
val%=7;
node x2=a[x];
for(int i=0;i<=6;i++)
a[x].val[(i+val)%7]=x2.val[i];
return ;
}
void treeAddLazy(int x,int val)
{
a[x].lazy+=val;
treeAddVal(x,val);
}
void treeUpdate(int x)
{
memset(a[x].val,0,sizeof(a[x].val));
for(int i=0;i<=6;i++)
a[x].val[i]=a[a[x].ls].val[i]+a[a[x].rs].val[i];
}
void treeBuild(int l,int r)
{
int now=++len;
a[now].l=l;a[now].r=r;a[now].mid=(l+r)/2;
a[now].lazy=0;
if(l==r)
a[now].val[readVal[l]%7]++;
else
{
a[now].ls=len+1;
treeBuild(l,a[now].mid);
a[now].rs=len+1;
treeBuild(a[now].mid+1,r);
treeUpdate(now);
}
return;
}
int treeGetAns(int now,int l,int r)
{
if(a[now].l==a[now].r||(a[now].l==l&&a[now].r==r))return a[now].val[0];
if(a[now].lazy)
{
treeAddLazy(a[now].ls,a[now].lazy);
treeAddLazy(a[now].rs,a[now].lazy);
a[now].lazy=0;
}
treeUpdate(now);
int ans=0;
if(l<=a[now].mid)ans+=treeGetAns(a[now].ls,l,min(r,a[now].mid));
if(r>=a[now].mid+1)ans+=treeGetAns(a[now].rs,max(l,a[now].mid+1),r);
treeUpdate(now);
return ans;
}
void treeAdd(int now,int l,int r,int val)
{
if(a[now].l==a[now].r)
{
treeAddVal(now,val);
return;
}
if(a[now].l==l&&a[now].r==r)
{
treeAddLazy(now,val);
return;
}
if(a[now].lazy)
{
treeAddLazy(a[now].ls,a[now].lazy);
treeAddLazy(a[now].rs,a[now].lazy);
a[now].lazy=0;
}
if(l<=a[now].mid)treeAdd(a[now].ls,l,min(r,a[now].mid),val);
if(r>=a[now].mid+1)treeAdd(a[now].rs,max(l,a[now].mid+1),r,val);
treeUpdate(now);
return;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&readVal[i]);
treeBuild(1,n);
scanf("%d",&m);
while(m--)
{
scanf("%s",ss+1);
int x,y,z;
if(ss[1]==
{
scanf("%d%d",&x,&y);
printf("%d\n",treeGetAns(1,x,y));
}
else
{
scanf("%d%d%d",&x,&y,&z);
treeAdd(1,x,y,z);
}
}
return 0;
}