HDU4267 A Simple Problem with Integers 线段树/树状数组
2012长春网络赛A题
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 1
14
2 1
2 2
2 3
2 4
1 2 3 1 2
2 1
2 2
2 3
2 4
1 1 4 2 1
2 1
2 2
2 3
2 4
Sample Output
1
1
1
1
1
3
3
1
2
3
4
1
树状数组:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int maxn=50005; int N,Q; int val[maxn]; int add[maxn][11][10]; int op,a,b,k,c; inline int lowbit(int x){ return x & -x;} inline void _add(int pos, int val, int k, int x){ for(; pos <= N; pos += lowbit(pos)) add[pos][k][x] += val; } inline void update(int l, int r, int val, int k, int x){ _add(l, val, k, x); _add(r+1, -val, k, x); } int _sum(int pos, int k, int x){ int res = 0; for(; pos >= 1; pos -= lowbit(pos)) res += add[pos][k][x]; return res; } int query(int p) { for(int k=1;k<11;k++){ for(int x=0;x<k;x++){ if(p%k==x%k){ int tmp=_sum(p,k,x); val[p]+=tmp; update(p,p,-tmp,k,x); } } } return val[p]; } int main() { freopen("in.txt","r",stdin); while(~scanf("%d",&N)){ memset(add,0,sizeof(add)); for(int i=1;i<=N;i++) scanf("%d",&val[i]); scanf("%d",&Q); while(Q--){ scanf("%d",&op); if(op==1){ scanf("%d%d%d%d",&a,&b,&k,&c); update(a,b,c,k,a%k); } else{ scanf("%d",&a); printf("%d\n",query(a)); } } } return 0; }
线段树:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int maxn=50005; int N; struct SegTree { int val; int add[55]; }; SegTree T[maxn*3]; int op,a,b,k,c; int Q; int ID[11][11]; void Init() { int id=0; for(int k=1;k<11;k++){ for(int x=0;x<k;x++){ ID[k][x]=id++; } } } void build(int l,int r,int rt) { T[rt].val=0; memset(T[rt].add,0,sizeof(T[rt].add)); if(l==r){ scanf("%d",&T[rt].val); return; } int m=(l+r)>>1; build(lson); build(rson); } void push_down(int rt) { for(int k=1;k<11;k++){ for(int x=0;x<k;x++){ int id=ID[k][x]; T[rt<<1].add[id]+=T[rt].add[id]; T[rt<<1|1].add[id]+=T[rt].add[id]; T[rt].add[id]=0; } } } void update(int L,int R,int c,int id,int l,int r,int rt) { if(L<=l&&r<=R){ T[rt].add[id]+=c; return; } push_down(rt); int m=(l+r)>>1; if(L<=m) update(L,R,c,id,lson); if(R>m) update(L,R,c,id,rson); } int query(int p,int l,int r,int rt) { if(l==r){ for(int k=1;k<11;k++){ for(int x=0;x<k;x++){ int id=ID[k][x]; if(l%k==x%k) T[rt].val+=T[rt].add[id]; T[rt].add[id]=0; } } return T[rt].val; } push_down(rt); int m=(l+r)>>1; if(p<=m) return query(p,lson); else return query(p,rson); } int main() { freopen("in.txt","r",stdin); while(~scanf("%d",&N)){ Init(); build(1,N,1); scanf("%d",&Q); while(Q--){ scanf("%d",&op); if(op==1){ scanf("%d%d%d%d",&a,&b,&k,&c); int id=ID[k][a%k]; update(a,b,c,id,1,N,1); } else{ scanf("%d",&a); printf("%d\n",query(a,1,N,1)); } } } return 0; }