【树状数组区间修改单点查询+分组】HDU 4267 A Simple Problem with Integers

http://acm.hdu.edu.cn/showproblem.php?pid=4267

【思路】

  • 树状数组的区间修改:在区间[a, b]内更新+x就在a的位置+x. 然后在b+1的位置-x
  • 树状数组的单点查询:求某点a的值就是求数组中1~a的和.

  • (i-a)%k==0把区间分隔开了,不能直接套用树状数组的区间修改单点查询
  • 这道题的K很小,所以可以枚举k,对于每个k,建立k个树状数组,所以一共建立55棵树
  • 所以就可以多建几棵树..然后就可以转换为成段更新了~~

【AC】

 1 #include<bits/stdc++.h>
 2 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             else
57             {
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 }
树状数组

 

posted @ 2017-08-26 17:29  shulin15  阅读(159)  评论(0编辑  收藏  举报