hdu 4267 多维树状数组

题意:有一个序列

"1 a b k c" means adding c to each of Ai which satisfies a <= i <= b and (i - a) % k == 0. (1 <= a <= b <= N, 1 <= k <= 10, -1,000 <= c <= 1,000)
"2 a" means querying the value of Aa. (1 <= a <= N)

分析转自:http://www.cnblogs.com/Griselda/archive/2012/09/15/2686133.html

感觉是树状数组了

但是 树状数组是单点更新 而题目要求是在a b 内每隔 k 个数更新..

如果用for循环对a b 内每隔 k 个位置的数更新就会很费时间..

所以有一个方法就是 按 k 值 i%k 值还有 i/k+1 值把每隔 k 个位置的值都分组..即按 k 值和 i%k 值建树状数组

到时候维护其中一棵 树状数组就好了..

维护的方法是在c[ k ][a%k][(i-a)/k+1] + 1 在c[ k ][a % k ][ (a/k) + (b-a)/k + 2 ] - 1..

关于建成的树状数组..

更新时有55种情况
1,2,3,4,5......
1,3,5,7,9......
2,4,6,8,10....
1,4,7,10,13...
2,5,9,12,15...
3,6,10,13,16...
.
.
.
10,20,30,40,50...

所以用55个树状数组.

建出来的树并不是普通的1,2,3,4,这样的,而是有着间隔的,其实也就是建造了许多树状数组

 1 #include<stdio.h>
 2
 3 #include<queue>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<string.h>
 7 const int MAXN=50020;
 8
 9
10 int c[12][12][MAXN];
11 int n;
12
13 int lowbit(int x)
14 {
15     return x&(-x);
16 }
17
18 void update(int t1,int t2,int i,int val)
19 {
20     while(i<=n)
21     {
22         c[t1][t2][i]+=val;
23         i+=lowbit(i);
24     }
25
26 }
27 int sum(int t1,int t2,int i)
28 {
29
30     int s=0;
31     while(i>0)
32     {
33         s+=c[t1][t2][i];
34         i-=lowbit(i);
35     }
36     return s;
37 }
38 int num[MAXN];
39 int main()
40 {
41     //freopen("in.txt","r",stdin);
42     //freopen("out.txt","w",stdout);
43
44     int m;
45     while(scanf("%d",&n)!=EOF)
46     {
47         for(int i=0;i<n;i++)scanf("%d",&num[i]);
48         for(int i=0;i<12;i++)
49           for(int j=0;j<12;j++)
50             for(int k=0;k<MAXN;k++)
51               c[i][j][k]=0;
52         scanf("%d",&m);
53         int a,b,k,q;
54         int t;
55         while(m--)
56         {
57             scanf("%d",&t);
58             if(t==1)
59             {
60                 scanf("%d%d%d%d",&a,&b,&k,&q);
61                 a--;
62                 b--;
63                 int num=(b-a)/k;
64                 int s=a%k;
65                 update(k,s,a/k+1,q);
66                 update(k,s,a/k+num+2,-q);
67             }
68             else
69             {
70                 scanf("%d",&a);
71                 a--;
72                 int ss=num[a];
73                 for(int i=1;i<=10;i++)
74                 {
75                     ss+=sum(i,a%i,a/i+1);
76                 }
77                 printf("%d\n",ss);
78             }
79         }
80     }
81     return 0;
82 }
时间: 2024-10-28 13:19:43

hdu 4267 多维树状数组的相关文章

HDU 1892 二维树状数组

See you~ Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 3485    Accepted Submission(s): 1103 Problem Description Now I am leaving hust acm. In the past two and half years, I learned so many kno

hdu 1890 二维树状数组

#include<stdio.h> #include<string.h> #include<iostream> using namespace std; int sum[1010][1010]; int mark[1010][1010]; int add(int a,int b,int c) { int i,j; for(i=a;i<=1001;i+=(i&-i)) for(j=b;j<=1001;j+=(j&-j)) sum[i][j]+=

HDU 5465 Clarke and puzzle Nim游戏+二维树状数组

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle Accepts: 42 Submissions: 269 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 克拉克是一名人格分裂患者.某一天,有两个克拉克(aa和bb)在玩一个方格游戏. 这个方格是一个n*mn∗m的矩阵,每个格子里有一

hdu 5517 Triple(二维树状数组)

题目链接:hdu 5517 Triple 题意: 有n个两元组A,有m个三元组B,然后set C有一个计算方式. 现在让你找set TOP的size. 题解: 理解题意后,显然对于每个b的分组,只有最大的a才有贡献, 然后就可以发现set B中每个元素按照e分组后,只会对应一个a,所以最多有1e5个三元组可能有贡献. 然后将这个三元组排一下序,用二维树状数组搞搞就行了. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=(a);i&l

hdu 4456 Crowd(二维树状数组)

题目链接:hdu 4456 Crowd 题目大意:给定N,然后M次操作 1 x y z:在x,y的位置加z 2 x y z:询问与x,y曼哈顿距离小于z的点值和. 解题思路:将矩阵旋转45度,然后询问就等于是询问一个矩形,可以用容斥定理搞,维护用二维树状数组,但是空间开 不下,直接用离散化,将有用到的点处理出来. #include <cstdio> #include <cstring> #include <algorithm> using namespace std;

HDU 1892 See you~ (二维树状数组)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1892 See you~ Problem Description Now I am leaving hust acm. In the past two and half years, I learned so many knowledge about Algorithm and Programming, and I met so many good friends. I want to say so

HDU_4456_二维树状数组

http://acm.hdu.edu.cn/showproblem.php?pid=4456 第一道二维树状数组就这么麻烦,题目要计算的是一个菱形范围内的和,于是可以把原来的坐标系旋转45度,就是求一个正方形范围内的和,这里还涉及到坐标系平移和放大,由于题目数据较大,用了离散化来保存需要处理的点,放在h数组内,对应的二维树状数组存在tree数组内. #include<iostream> #include<cstring> #include<cstdio> #includ

hdu6078 Wavel Sequence dp+二维树状数组

//#pragma comment(linker, "/STACK:102400000,102400000") /** 题目:hdu6078 Wavel Sequence 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6078 题意:给定a序列和b序列.从a中取一个子序列x(数的位置顺序保持不变),子序列每个数满足a1<a2>a3<a4>a5<a6... 波浪形 从b中取相同长度的子序列y,也满足波浪形. 如果x

HDU1559 最大子矩阵 (二维树状数组)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1559 最大子矩阵 Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2901    Accepted Submission(s): 1454 Problem Description 给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使