嗜血魂K

导航

hdu1166

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>

using namespace std;

const long maxn = 50000;
const unsigned long inf = ~0U >> 2;

long T, N, man[maxn+10];
char com[10];

struct SegTree{
long l, r, sum;
}tree[maxn*5];

void buildTree(long v, long left, long right)
{
// if(v == 1) cout << "build..." << endl;
long mid = (left+right)/2;
tree[v].l = left; tree[v].r = right;
if(left == right) { tree[v].sum = man[left]; return; }
else{
buildTree(v*2, left, mid);
buildTree(v*2+1, mid+1, right);
}

tree[v].sum = tree[v*2].sum + tree[v*2+1].sum;
}

void updateTree(long v, long right, long num)
{
// if(v == 1) cout << "update..." << endl;
long mid = (tree[v].l+tree[v].r)/2;
tree[v].sum += num;
if(tree[v].l == tree[v].r) return;
else {
if(right <= mid) updateTree(v*2, right, num);
else updateTree(v*2+1, right, num);
}
}

long queryTree(long v, long left, long right)
{
// if(v == 1) cout << "query..." << endl;
long mid = (tree[v].l+tree[v].r)/2;
if(left == tree[v].l && right == tree[v].r) return tree[v].sum;
else return (left <= mid ? queryTree(2*v, left, min(right, mid)) : 0) + (right > mid ? queryTree(2*v+1, max(mid+1, left), right) : 0);
}

int main()
{
#ifdef LOCAL
freopen("hdu1166.in", "r", stdin);
#endif
long a, b;
scanf("%ld", &T);
for(long t = 1; t <= T; t++) {
printf("Case %ld:\n", t);
scanf("%ld", &N);
for(long i = 1; i <= N; i++) scanf("%ld", man+i);
buildTree(1, 1, N);
while(scanf("%s", com)) {
if(!strcmp(com, "End")) break;
scanf("%ld%ld", &a, &b);
if(!strcmp(com, "Query")) cout << queryTree(1, a, b) << endl;
else {
if(!strcmp(com, "Add")) updateTree(1, a, b);
else updateTree(1, a, -b);
}
}
}
return 0;
}

嘛...初学线段树

 

这是第二次写了,虽然比起基本模型多了个add/sub,其实方法差不多,很好写...只是build函数居然忘记写tree[v].l = left, tree[v].r = right = =

 

之后因为太久没写这种题的缘故吧?输入数据一坨的,scanf %s%ld%ld写一起,一组数据倒没问题,要是多几组,读入End时会把下一组的读掉..><

posted on 2012-04-05 13:47  嗜血魂K  阅读(270)  评论(0编辑  收藏  举报