【思路】
- 树状数组的区间修改:在区间[a, b]内更新+x就在a的位置+x. 然后在b+1的位置-x
-
树状数组的单点查询:求某点a的值就是求数组中1~a的和.
- (i-a)%k==0把区间分隔开了,不能直接套用树状数组的区间修改单点查询
- 这道题的K很小,所以可以枚举k,对于每个k,建立k个树状数组,所以一共建立55棵树
-
所以就可以多建几棵树..然后就可以转换为成段更新了~~
【AC】
1 #include2 using namespace std; 3 typedef long long ll; 4 int n; 5 const int maxn=5e4+2; 6 int tree[12][12][maxn]; 7 int a[maxn]; 8 int lowbit(int x) 9 {10 return x&(-x);11 }12 void add(int k,int x,int pos,int val)13 {14 while(pos<=n)15 {16 tree[k][x][pos]+=val;17 pos+=lowbit(pos);18 }19 }20 21 int query(int k,int x,int pos)22 {23 int res=0;24 while(pos)25 {26 res+=tree[k][x][pos];27 pos-=lowbit(pos);28 }29 return res;30 }31 int main()32 {33 while(~scanf("%d",&n))34 {35 memset(tree,0,sizeof(tree));36 for(int i=1;i<=n;i++)37 {38 scanf("%d",&a[i]);39 }40 int q;41 scanf("%d",&q);42 while(q--)43 {44 int tp;45 scanf("%d",&tp);46 if(tp==1)47 {48 int x,y,k,c;49 scanf("%d%d%d%d",&x,&y,&k,&c);50 int st=x/k;51 if(x%k) st++;52 int ed=st+(y-x)/k; 53 add(k,x%k,st,c);54 add(k,x%k,ed+1,-c);55 }56 else57 {58 int x;59 scanf("%d",&x);60 int ans=a[x];61 int pos;62 for(int i=1;i<=10;i++)63 {64 pos=x/i;65 if(x%i) pos++;66 ans+=query(i,x%i,pos);67 }68 printf("%d\n",ans);69 }70 } 71 }72 return 0;73 }