题意:给出一个长为n的序列,然后有q个操作,有两种操作方式
1.输入a,b,k,c,表示将区间[a,b]中的数i满足(i-a)%k == 0加上c.
2.输入一个数y,输出序列中第y个数的值。
思路:如果是使得一个区间(L,R)的值加上c,那么我们可以让a[L]+c,a[R+1]-c,求个前缀即可知道增加了多少
但这里是隔k个+c,由于k很小,所以我们可以定义a[k][i%k][x],用树状数组来维护
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=50005; 4 5 int a[12][12][N]; 6 int b[N]; 7 int n; 8 9 void add(int i,int j,int x,int val){ 10 while(x<=n){ 11 a[i][j][x]+=val; 12 x+=(x)&(-x); 13 } 14 } 15 16 int getsum(int i, int j, int x) 17 { 18 int sum=0; 19 while(x>0) 20 { 21 sum+=a[i][j][x]; 22 x-=(x)&(-x); 23 } 24 return sum; 25 } 26 int main(){ 27 28 while(~scanf("%d",&n)){ 29 memset(a,0,sizeof(a)); 30 for(int i=1;i<=n;i++) { 31 scanf("%d",&b[i]); 32 } 33 int q; 34 scanf("%d",&q); 35 for(int i=1;i<=q;i++){ 36 int type; 37 scanf("%d",&type); 38 if(type==1){ 39 int l,r,k,c; 40 scanf("%d%d%d%d",&l,&r,&k,&c); 41 add(k, l%k, l, c); 42 add(k, l%k, r+1, -c); 43 } 44 else { 45 int x; 46 scanf("%d",&x); 47 int sum=b[x]; 48 for(int i=1;i<=10;i++){ 49 sum+=getsum(i,x%i,x); 50 } 51 printf("%d ",sum); 52 } 53 } 54 } 55 }