HDU 4267 A Simple Problem with Integers --树状数组
题意:给一个序列,操作1:给区间[a,b]中(i-a)%k==0的位置 i 的值都加上val 操作2:查询 i 位置的值
解法:树状数组记录更新值。 由 (i-a)%k == 0 得知 i%k == a%k,又因为k <= 10,想到建55棵树状数组,即对每个(k,x%k)都建一棵树状数组,每次更新时,在第(k,a%k)棵树状数组上更新a这个点,更新值为val,然后再b+1处更新值为-val,即在[a,b]内更新了val。
查询pos的时候,求出每一个树状数组(k,pos%k)的sum值即可。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[N][11][11]; int n,ka[N]; int lowbit(int x){ return x & (-x); }; void modify(int pos,int k,int mod,int val) { if(pos == 0) return; while(pos <= n) { c[pos][k][mod] += val; pos += lowbit(pos); } } int getsum(int pos) { int res = 0; int tmp = pos; while(pos > 0) { for(int i=1;i<=10;i++) res += c[pos][i][tmp%i]; pos -= lowbit(pos); } return res; } int main() { int m,a,b,k,val,i,j; int op; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&ka[i]); memset(c,0,sizeof(c)); scanf("%d",&m); while(m--) { scanf("%d",&op); if(op == 1) { scanf("%d%d%d%d",&a,&b,&k,&val); modify(a,k,a%k,val); modify(b+1,k,a%k,-val); } else { scanf("%d",&a); printf("%d\n",ka[a] + getsum(a)); } } } return 0; }
作者:whatbeg
出处1:http://whatbeg.com/
出处2:http://www.cnblogs.com/whatbeg/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
更多精彩文章抢先看?详见我的独立博客: whatbeg.com