NKOI 1321--数列操作问题(裸BIT)
数列操作问题
Time Limit:10000MS Memory Limit:65536K
Total Submit:276 Accepted:149
Case Time Limit:1000MS
Description
假设有一列数{Ai}(1≤i≤n),支持如下两种操作:
将Ak的值加D。(k, D是输入的数)
输出As+As+1+…+At。(s, t都是输入的数,S≤T)
Input
第一行一个整数n,
第二行为n个整数,表示{Ai}的初始值≤10000。
第三行为一个整数m,表示操作数
下接m行,每行描述一个操作,有如下两种情况:
ADD k d (表示将Ak加d,1<=k<=n,d为数,d的绝对值不超过10000)
SUM s t (表示输出As+…+At)
Output
对于每一个SUM提问,输出结果
Sample Input
5
1 2 3 2 4
5
SUM 1 2
SUM 1 5
ADD 1 2
SUM 1 2
SUM 1 5
Sample Output
3
12
5
14
Hint
M,N<=100000
Source
解题思路:
模板题
代码:
# include<cstdio> # include<iostream> # include<fstream> # include<algorithm> # include<functional> # include<cstring> # include<string> # include<cstdlib> # include<iomanip> # include<numeric> # include<cctype> # include<cmath> # include<ctime> # include<queue> # include<stack> # include<list> # include<set> # include<map> using namespace std; const double PI=4.0*atan(1.0); typedef long long LL; typedef unsigned long long ULL; # define inf 999999999 # define MAX 100000+4 int n; int a[MAX]; int tree[MAX];//树状数组 char s[23]; int read ( int pos ) { int temp = 0; for ( int j = pos;j;j-=j&(-j) ) { temp+=tree[j]; } return temp; } void update( int pos,int val ) { for ( int j = pos;j <= n;j+=j&(-j) ) { tree[j]+=val; } } int main(void) { char c; scanf("%d",&n); for ( int i = 1;i <= n;i++ ) { scanf("%d",&a[i]); } for ( int i = 1;i <= n;i++ ) { update(i,a[i]); } int m;scanf("%d\n",&m); for ( int i = 0;i < m;i++ ) { int x,y; int ans1 = 0; int ans2 = 0; scanf("%s",s); scanf("%d",&x); scanf("%d",&y); //cout<<x<<" "<<y<<endl; if ( s[0] == 'S' ) { ans1 = read(y); ans2 = read(x-1); printf("%d\n",ans1-ans2); } else if ( s[0] == 'A' ) { update(x,y); } } return 0; }