HDU 4267 (树状数组)
来源:互联网 发布:php extension dir 编辑:程序博客网 时间:2024/05/16 06:45
A Simple Problem with Integers
Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5833 Accepted Submission(s): 1871
Problem Description
Let A1, A2, ... , AN be N elements. You need to deal with two kinds of operations. One type of operation is to add a given number to a few numbers in a given interval. The other is to query the value of some element.
Input
There are a lot of test cases.
The first line contains an integer N. (1 <= N <= 50000)
The second line contains N numbers which are the initial values of A1, A2, ... , AN. (-10,000,000 <= the initial value of Ai <= 10,000,000)
The third line contains an integer Q. (1 <= Q <= 50000)
Each of the following Q lines represents an operation.
"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)
Output
For each test case, output several lines to answer all query operations.
Sample Input
4 1 1 1 1142 12 22 32 41 2 3 1 22 1 2 22 32 41 1 4 2 12 12 22 32 4
Sample Output
111113312341
Source
2012 ACM/ICPC Asia Regional Changchun Online
又是树状数组的专题,好多都做过,以为没有什么能够难倒我,然而还是有些题目虽然做出来了但是废了点周折。
这题的话,就是区间修改单点查询,但是不同之处在于,在一个区间内,他不是全部都修改,而是隔几个的修改。例如说,当k=2的时候,对于区间[l,r],修改l、l+2,l+4,……然后k是给定的,满足1 <= k <= 10。
初看没有什么思路,直接全部修改肯定不行,暴力修改肯定超时。但是很快萌生一个思路:既然k的取值比较小,我可以进行分组,令每一个k的取值为一组,然后建立树状数组。在去吃饭的路上,有了大体的想法,每一组建立的树状数组设置为二维,以k=10的组为例,按顺序每行放十个数字,这样对于一个修改操作[l,r],我们修改的是l、l+2,l+4……相当于这个二维树状数组中l所在的列。
乍一看,这个方法似乎可行,但是回来之后发现实现起来并不简单。于是便摒弃这个想法,把分组变多,然后每个组建立一个一维的树状数组。注意到当k=1时,仅有一种分组;当k=2时,有两种分组,分别是以1和2为开始的两组;当k=3的时,有3种分组,分别是以1、2和3为开始的两组……这样总共有55个分组。为了表示的方便,我建立一个树状数组类型的二维数组BIT[k][i],表示间隔k且以i为开头的组的树状数组。不难发现,这样子分组之后,每一个确定的数字i的最后取值就取决于与之相关的10个树状数组。我们在修改的时候,只修改对应的一棵树状数组,然后查询的时候把相关点相关的10个树状数组的值相加并加上初始值即可。
另外,注意所有的树状数组所保存的值都是改变量,所以最后要加上初始值,并不需要把初始值初始化给每一个树状数组。还有一点,就是分组之后,我并没有把组内的数字重标号,即组内的有效点是离散的,例如一个组:1、3、5、7,如果修改[1,5],实际上是1~5包括偶数都修改的,可能会觉得偶数修改会错,但是实际上分组之后真正有效的还是只有1、3、5、7,即即使修改了偶数也不会对结果产生影响。这个具体理解一下我的问答的操作就会知道。具体代码如下:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstdlib>#include<cmath>#include<cstring>#include<iomanip>#define N 50100using namespace std;int n,a[N];struct DifferenceBIT{int c[N];inline int lowbit(int x){return x&-x;}inline void updata(int x,int k){while (x<=n){c[x]+=k;x+=lowbit(x);}}inline int getsum(int x){int res=0;while (x>0){res+=c[x];x-=lowbit(x);}return res;}} BIT[12][12];int getsum(int x){ int res=0; for(int k=1;k<=10;k++) res+=BIT[k][x%k].getsum(x);//只加上真实含有x的组的树状数组值 return res;}int main(){ while (~scanf("%d",&n)) { memset(BIT,0,sizeof(BIT)); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int q; scanf("%d",&q); while (q--) { int op; scanf("%d",&op); if (op==2) { int x; scanf("%d",&x); printf("%d\n",getsum(x)+a[x]); } else { int l,r,k,x; scanf("%d%d%d%d",&l,&r,&k,&x); BIT[k][l%k].updata(l,x); BIT[k][l%k].updata(r+1,-x); } } } return 0;}
- HDU 4267 (树状数组)
- HDU 4267 经典树状数组
- hdu (3874)树状数组
- hdu 2352(树状数组)
- HDU 1556(树状数组)
- hdu 5493 (树状数组)
- HDU 4911 (树状数组)
- 树状数组(hdu 1166)
- HDU 1394 (树状数组)
- hdu 4031(树状数组+辅助数组)
- HDU 4267 A Simple Problem with Integers(树状数组)
- HDU-4267-A Simple Problem with Integers-(树状数组)
- 分状态的树状数组hdu 4267
- HDU 3525(树状数组求解LCS)
- HDU-1541 树状数组(基础题)
- hdu 1892(二维树状数组模板)
- HDU 4339 Query(树状数组+二分)
- hdu 3584 (三维树状数组模板 )
- F-散度(F-divergence)
- 最大连续子序列
- spring常用的几个aware bean接口:
- 重装ubuntu后的第二天——openCV库的安装
- 多对多 二级缓存
- HDU 4267 (树状数组)
- 七夕节
- Python如何给文件按顺序重命名
- 【卡尔曼滤波经典讲解,C++算法实现】
- BLE
- 【U3D】AABB包围体
- 51NOD1284 2 3 5 7的倍数
- 2.同步(Synchronization)
- Javascript--File对象