您的位置:首页 > 其它

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

2017-08-26 17:29 423 查看
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 }


树状数组
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐