一个很不错的题;
刚刚看到这个题目就感觉要用线段树或者树状数组,但是有感觉有点不同;
敲了一发简单的线段树之后果断的T了;
网上一搜题解,发现要用55颗线段树或者树状数组;
一共有k种树,然后每种树根据他们%k的余数的不同又分成好几颗;
然后最后统计的时候只要对每个节点统计这k种树种的信息就行;
1 #include<cstdio> 2 #include<cstring> 3 #define maxn 50005 4 using namespace std; 5 6 int d[100][maxn],num[maxn]; 7 int n,q; 8 void insert(int k,int p,int v) 9 { 10 while(p<=n) 11 { 12 d[k][p]+=v; 13 p+=p&-p; 14 } 15 } 16 17 int query(int p) 18 { 19 int ret=0; 20 for(int i=0; i<10; i++) 21 { 22 int k=i*10+p%(i+1); 23 for(int j=p; j>0; j-=j&-j)ret+=d[k][j]; 24 } 25 return num[p]+ret; 26 } 27 28 int main() 29 { 30 int cmd,a,b,k,c; 31 while(scanf("%d",&n)!=EOF) 32 { 33 memset(d,0,sizeof d); 34 for(int i=1; i<=n; i++)scanf("%d",&num[i]); 35 scanf("%d",&q); 36 for(int i=0; i<q; i++) 37 { 38 scanf("%d",&cmd); 39 if(cmd==1) 40 { 41 scanf("%d%d%d%d",&a,&b,&k,&c); 42 b-=(b-a)%k; 43 int p=(k-1)*10+a%k; 44 insert(p,a,c); 45 insert(p,b+1,-c); 46 } 47 else 48 { 49 scanf("%d",&a); 50 printf("%d ",query(a)); 51 } 52 } 53 } 54 return 0; 55 }