题目:HDU 1166 敌兵布阵
线段树模板题同时也是树状数组模板题,两种解法:
线段树:
//Must so #include<bits/stdc++.h> #define mem(a,x) memset(a,x,sizeof(a)) #define sqrt(n) sqrt((double)n) #define pow(a,b) pow((double)a,(int)b) #define inf 1<<29 #define NN 50004 using namespace std; const double PI = acos(-1.0); typedef long long LL; struct Node { int l,r,v; }q[4*NN]; void buildtree(int i,int l,int r) { q[i].l = l,q[i].r = r; if (l == r) { scanf("%d",&q[i].v); return ; } int mid = (l+r)/2; buildtree(i<<1,l,mid); buildtree((i<<1)+1,mid+1,r); q[i].v = q[i<<1].v + q[(i<<1)+1].v; } void Add(int i,int a,int b) { if (q[i].l == q[i].r &&q[i].l == a) { q[i].v += b; return ; } int mid = (q[i].l+q[i].r)/2; if (a <= mid) Add(i<<1,a,b); else Add((i<<1)+1,a,b); q[i].v += b; } int query(int i,int l,int r) { if (l == q[i].l&&r == q[i].r) { return q[i].v; } int mid = (q[i].l+q[i].r)/2; if (r <= mid) return query(i<<1,l,r); else if (l > mid) return query((i<<1)+1,l,r); else return query(i<<1,l,mid)+query((i<<1)+1,mid+1,r); } int main() { int T; scanf("%d",&T); int kas = 1; while (T--) { printf("Case %d:\n",kas++); int n; scanf("%d",&n); buildtree(1,1,n); string s; while (cin>>s) { if (s == "End") break; int a,b; scanf("%d%d",&a,&b); if (s == "Query") { printf("%d\n",query(1,a,b)); } else if (s == "Add") { Add(1,a,b); } else { Add(1,a,-b); } } } return 0; }
这是本渣第一道线段树的题,表示对移位运算符的优先级非常不满
树状数组:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> #include<stdlib.h> #include<cctype> #include<map> #define mem(a,x) memset(a,x,sizeof(a)) #define esp 1e-8 using namespace std; typedef long long ll; const int N = 50000; int c[N+5],n; int lowbit(int x) { return x&(-x); } void Add(int i,int v)//将第i个元素的值修改成v { while (i <= n) { c[i] += v; i += lowbit(i); } } int Sun(int i)//求前i项和 { int s = 0; while (i > 0) { s += c[i]; i -= lowbit(i); } return s; } int main() { int T;scanf("%d",&T); int kas = 0; while (T--) { scanf("%d",&n); mem(c,0); for (int i = 1,v;i <= n;++i) { scanf("%d",&v); Add(i,v); } printf("Case %d:\n",++kas); string s; while (cin>>s) { if (s == "End") break; int x,y;scanf("%d %d",&x,&y); if (s == "Add") { Add(x,y); } else if (s == "Sub") { Add(x,-y); } else printf("%d\n",Sun(y)-Sun(x-1)); } } return 0; }
大神给的成神之路:点我开启成神之路~~~