前天加了個acm羣,羣裏一個人問的一個問題 看了一下,雖然知道是用線段樹或者樹狀數組做,但是自己確不會這兩種數據結構
看了看,貢獻了無數次wa後,藉助模板過了
題意很簡單,就是求子段和, 但是由於數據量較大,普通的方法肯定超時,所以用樹狀數組。
數據量大隻能用scanf 和printf 用cin 和cout超時
代碼如下:
#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> using namespace std; #define lowbit(x) ((x)&((x)^((x)-1))) #define MAXN 100010 typedef long long elem_t; struct sum { elem_t a[MAXN],c[MAXN],ret; int n; void init(int i) { memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); n=i; } void update(int i,elem_t v) { for (v-=a[i],a[i++]+=v;i<=n;c[i-1]+=v,i+=lowbit(i)); } elem_t query(int i) { for (ret=0;i;ret+=c[i-1],i^=lowbit(i)); return ret; } }; int main() { int T; scanf("%d",&T); sum a; while (T--) { int x; scanf("%d",&x); a.init(x); int i(0); while (i<x) { long long temp; scanf("%lld",&temp); a.update(i,temp); ++i; } int ques; scanf("%d",&ques); getchar(); char op[10]; while (ques--) { int index1,index2; long long num; scanf("%s",op); if (!strcmp(op,"Add")) { scanf("%d%lld",&index1,&num); a.update(index1-1,num+a.a[index1-1]); } else if (!strcmp(op,"Delete")) { scanf("%d%lld",&index1,&num); if (num>a.a[index1-1]) a.update(index1-1,0); else a.update(index1-1,a.a[index1-1]-num); } else if (!strcmp(op,"Inquire")) { scanf("%d%d",&index1,&index2); printf("%lld/n",a.query(index2)-a.query(index1-1)); } } } return 0; }