题意:
给定一个长度为n<=50000的数列。对这个数列进行Q此操作。有两种操作:
操作1:给定a,b,k,c四个整数,使得a,b间满足a<=i<=b,且(i-a)%k==0的数加c. k<=10
操作2:给定整数a,求A[a].
分析:
对于操作1,显然(i-a)%k == 0 <=> i%k = a % k , 记为e。
那么一共有55种(k,e),则维护55个数据结构,执行区间更新,点查询。
【1】如果使用一般线段树,55*N*3的内存,MLE。只给了32M的内存。。。跪烂
【2】考虑使用树状数组,55*N的内存。
Mark:树状数组真是好用,内存小,代码量小。
【1】点更新,区间查询。
【1】区间更新,点查询。
有空补上树状数组的模板,
贴个代码


1 #include<stdio.h> 2 #include<math.h> 3 #include<string.h> 4 #define N 50501 5 6 int n; 7 long long seq[N]; 8 9 long long tree[56][N]; 10 int hash[11][11]; 11 12 int lowbit(int x) 13 { 14 return x&(-x); 15 } 16 void up(int tmp,int pos,long long val) 17 { 18 while (pos < N) 19 { 20 tree[tmp][pos] += val; 21 pos += lowbit(pos); 22 } 23 return ; 24 } 25 long long getsum(int tmp, int pos) 26 { 27 long long res = 0; 28 while (pos > 0) 29 { 30 res += tree[tmp][pos]; 31 pos -= lowbit(pos); 32 } 33 return res; 34 } 35 36 int get(int pp,int kk){ 37 if (pp % kk == 0) 38 return pp/kk; 39 else 40 return pp/kk + 1; 41 } 42 long long query(int i,int pos) 43 { 44 int j = pos % i; 45 int tmp = hash[i][j]; 46 pos = get(pos,i); 47 long long res = getsum(tmp,pos); 48 return res; 49 } 50 51 void update(int l,int r,int i,long long val) 52 { 53 int j = l % i; 54 int tmp = hash[i][j]; 55 56 int ll = get(l,i); 57 int rr = get(r,i); 58 //printf("%d %d\n",ll,rr); 59 60 rr = ll + (r - l)/i; 61 up(tmp,ll,val); 62 up(tmp,rr+1,-val); 63 return ; 64 } 65 int main() 66 { 67 // printf("%d\n",get(10,5)); 68 int t = 0; 69 for (int i=1; i<=10; i++) 70 for (int j=0; j<i; j++){ 71 hash[i][j] = t++; 72 } 73 74 while (scanf("%d",&n)==1) 75 { 76 memset(tree,0,sizeof(tree)); 77 for (int i=1; i<=n; i++) 78 scanf("%I64d",&seq[i]); 79 80 int m; 81 scanf("%d",&m); 82 while (m--) 83 { 84 int id; 85 scanf("%d",&id); 86 if (id == 1) 87 { 88 int l,r,k; 89 long long c; 90 91 scanf("%d%d%d%I64d",&l,&r,&k,&c); 92 if (l > r){ 93 int tmp = l; 94 l = r; 95 r = tmp; 96 } 97 update(l,r,k,c); 98 } 99 else 100 { 101 int pos; 102 scanf("%d",&pos); 103 long long ans = seq[pos]; 104 for (int i=1; i<=10; i++){ 105 ans += query(i,pos); 106 } 107 printf("%I64d\n",ans); 108 } 109 } 110 } 111 return 0; 112 }
本文介绍了一种使用树状数组解决特定区间操作问题的方法,包括区间更新和点查询。通过对55种可能的操作类型进行预处理,利用树状数组的高效特性,解决了给定数列上的复杂操作需求。
6万+

被折叠的 条评论
为什么被折叠?



