重走算法之路——树状数组,线段树,张昆玮线段树(这里运行时间还体现不出彼此的区别)

http://acm.hdu.edu.cn/showproblem.php?pid=1166

树状数组:265ms

//#pragma comment(linker, "/STACK:61400000,61400000")
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

#define pi 3.1415926535897932385
#define LL64 __int64
#define LL long long
#define oo 2147483647
#define N 50010
#define M 210
#define INF 1e9

int a[N];

int lowbit(int m)
{
return m & (m ^ (m - 1));
}

int sum(int m)
{
int s = 0;
while (m > 0)
{
s += a[m];
m -= lowbit(m);
}

return s;
}

void update(int i, int x, int n)
{
while (i <= n)
{
a[i] += x;
i += lowbit(i);
}
}

int main()
{
int t;

//freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
int _case = 1;
scanf("%d", &t);
//while (t--)
for (int _case = 1; _case <= t; _case++)
//while (~scanf("%d%d", &n, &m))
{
int n;
memset(a, 0, sizeof(a));
printf("Case %d:\n", _case);
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
int x;
scanf("%d", &x);
update(i, x, n);
}
char x[10];
scanf("%s", x);
while (x[0] != 'E')
{
int ll, rr;
scanf("%d%d", &ll, &rr);
if (x[0] == 'Q')
{
printf("%d\n", sum(rr) - sum(ll - 1));
}
else
{
if (x[0] == 'A') update(ll, rr, n);
else update(ll, -rr, n);
}
scanf("%s", x);
}
}

return 0;
}

线段树:325ms
//#pragma comment(linker, "/STACK:61400000,61400000")
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

#define pi 3.1415926535897932385
#define LL64 __int64
#define LL long long
#define oo 2147483647
#define N 50010
#define M 210
#define INF 1e9

int s;

struct node
{
int l, r, mid, val;
}a[N * 3];

void create(int ll, int rr, int num)
{
a[num].l = ll;
a[num].r = rr;
a[num].mid = (ll + rr)>>1;
if (ll == rr)
{
scanf("%d", &a[num].val);
}
else
{
create(ll, a[num].mid, num * 2);
create(a[num].mid + 1, rr, num * 2 + 1);
a[num].val = a[num * 2].val + a[num * 2 + 1].val;
}
}

void query(int ll, int rr, int num)
{
if (a[num].l == ll && a[num].r == rr) s += a[num].val;
else
{
if (a[num].mid >= rr) query(ll, rr, num * 2);
else if (a[num].mid < ll) query(ll, rr, num * 2 + 1);
else
{
query(ll, a[num].mid, num * 2);
query(a[num].mid + 1, rr, num * 2 + 1);
}
}
}

void update(int ll, int rr, int num)
{
if (a[num].l == a[num].r) a[num].val += rr;
else
{
if (a[num].mid >= ll) update(ll, rr, num * 2);
else update(ll, rr, num * 2 + 1);
a[num].val = a[num * 2].val + a[num * 2 + 1].val;
}
}

int main()
{
int t;

//freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
int _case = 1;
scanf("%d", &t);
//while (t--)
for (int _case = 1; _case <= t; _case++)
//while (~scanf("%d%d", &n, &m))
{
int n;
printf("Case %d:\n", _case);
scanf("%d", &n);
create(1, n, 1);
char x[10];
scanf("%s", x);
while (x[0] != 'E')
{
int ll, rr;
scanf("%d%d", &ll, &rr);
if (x[0] == 'Q')
{
s = 0;
query(ll, rr, 1);
printf("%d\n", s);
}
else
{
if (x[0] == 'A') update(ll, rr, 1);
else update(ll, -rr, 1);
}
scanf("%s", x);
}
}

return 0;
}

zkw线段树:265ms

//#pragma comment(linker, "/STACK:61400000,61400000")
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

#define pi 3.1415926535897932385
#define LL64 __int64
#define LL long long
#define oo 2147483647
#define N 50010
#define M 210
#define INF 1e9

int l;
int T[N * 4];

void create(int n)
{
for (l = 1; l <= n + 1; l *= 2)//计算M
{

}
for (int i = l + 1; i <= l + n; i++)
{
scanf("%d", &T[i]);
}
for (int i = l; i > 0; i--)
{
T[i] = T[i * 2] + T[(i * 2) ^ 1];
}
}

int query(int s, int t)
{
int ans = 0;
for (s = s + l - 1, t = t + l + 1; s ^ t ^ 1 > 0; s >>= 1, t >>= 1)
{
if (~s & 1) ans += T[s + 1];//如果是左子树的左孩子,则处理左子树右孩子
if (t & 1) ans += T[t - 1];//如果是右子树的左孩子,则处理右子树左孩子
}

return ans;
}

void update(int n, int V)
{
for (T[n += l] += V, n >>= 1; n; n >>= 1)
{
T[n] = T[n + n] + T[n + n + 1];
}
}

int main()
{
int t;

//freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
int _case = 1;
scanf("%d", &t);
//while (t--)
for (int _case = 1; _case <= t; _case++)
//while (~scanf("%d%d", &n, &m))
{
int n;
memset(T, 0, sizeof(T));
printf("Case %d:\n", _case);
scanf("%d", &n);
create(n);
char x[10];
scanf("%s", x);
while (x[0] != 'E')
{
int ll, rr;
scanf("%d%d", &ll, &rr);
if (x[0] == 'Q')
{
printf("%d\n", query(ll, rr));
}
else
{
if (x[0] == 'A') update(ll, rr);
else update(ll, -rr);
}
scanf("%s", x);
}
}

return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值