题意:输入N 下面有N个数, Q个操作,对于每次操作 有两种情况。
情况1.输入1 a b k c,表示更新操作,将a-b区间内的符合a <= i <= b and (i - a) % k == 0.的数都+c。
情况2:输入2 a 表示查询操作,输出a 上的值。
如果用线段树暴力的话,妥妥的超时,需要延迟
思路:对于这种不是对整个区间都进行更新的操作,似乎lazy算法就没什么用了,这题一开始看的感觉是单点更新,但是看下数据量单点更新根本不可行。那我们可以想一下给的条件,(i-a)%k==0,可以化成i%k==a%k。对于a%k 就很好求了,所以我们可以枚举一下所有的mod 情况,因为k最大只是10,所以mod 的所有情况有55种。我们把这些mod 的情况都存下来,在更新的时候只更新(a%k)的,把(a%k)的都加起来,查询的时候在只把(i%k)的值加上,相当于用一个数组modleft[i][j]存一下某个数对于mod i 余数为j,这样就可以利用lazy的思想,只在查询的时候把值全部加起来,起到延迟标记的
#include
#include
#include
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
const int N = 50005;
struct node
{
int sum, lazy;
int add[56];
}tree[N<<2];
int mod[10][10];
void build(int l,int r,int rt);
void update(int L, int R, int k, int h,int c, int l, int r, int rt);
void pushdown(int rt);
int query(int pos,int l,int r,int rt);
int main()
{
memset(mod,0,sizeof(mod));
int cnt=0;
for(int i=1;i<=10;i++)
{
for(int j=0;j {
mod[i][j]=cnt++;
}
}
int n;
while(scanf("%d", &n)!=EOF)
{
build(1,n,1);
int q, num, pos, a, b, k, c;
scanf("%d", &q);
while(q--)
{
scanf("%d", &num);
if(num==1)
{
scanf("%d %d %d %d", &a, &b, &k, &c);
update(a,b,k,a%k,c,1,n,1);
}
else
{
scanf("%d", &pos);
printf("%d\n",query(pos,1,n,1));
}
}
}
return 0;
}
void build(int l,int r,int rt)
{
memset(tree[rt].add,0,sizeof(tree[rt].add));
tree[rt].lazy=0;
if(l==r)
{
scanf("%d", &tree[rt].sum);
return ;
}
int mid=(l+r)/2;
build(lson);
build(rson);
return ;
}
void update(int L, int R, int k, int h, int c,int l, int r, int rt)
{
if(l>=L&&r<=R)
{
tree[rt].lazy=1;
tree[rt].add[mod[k][h]]+=c;
return ;
}
pushdown(rt);
int mid=(r+l)/2;
if(mid>=L)
{
update(L,R,k,h,c,lson);
}
if(mid
update(L,R,k,h,c,rson);
}
return ;
}
void pushdown(int rt)
{
if(tree[rt].lazy)
{
tree[rt<<1].lazy=tree[rt<<1|1].lazy=1;
tree[rt].lazy=0;
for(int i=0;i<56;i++)
{
tree[rt<<1].add[i]+=tree[rt].add[i];
tree[rt<<1|1].add[i]+=tree[rt].add[i];
tree[rt].add[i]=0;
}
}
return ;
}
int query(int pos,int l,int r,int rt)
{
if(l==r)
{
int ans=tree[rt].sum;
for(int i=1;i<=10;i++)
{
ans+=tree[rt].add[mod[i][pos%i]];
tree[rt].add[mod[i][pos%i]]=0;
}
tree[rt].sum=ans;
return ans;
}
int mid=(l+r)/2;
pushdown(rt);
if(pos<=mid)
{
return query(pos,lson);
}
else
{
return query(pos,rson);
}
}