在第二场比赛中的k题用到了线段树,所以昨天和今天都在学习线段树,学习了线段树的单点更新以及查询,主要就是要建树、查询、更新,今天上午做了杭电上的1754,没想到今天下午的比赛就有这一道题,果断交了就a了。
先贴一下单点更新的及查询的模板:
<pre name="code" class="cpp">//最最基础的线段树,只更新叶子节点,然后把信息用PushUP(intr)这个函数更新上来
//1.bulid();
//2.query(a,b)
//3.update(a,b)
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
const int maxn=55555;
int sum[maxn<<2];
int n;
//根据题意做相关修改,询问时的操作
int operate(int a,int b) {
return a+b;
}
void PushUp(int rt) {
sum[rt] = operate(sum[rt<<1],sum[rt<<1|1]);
}
void bulid(int l=1,int r=n,int rt=1) {
if(l==r) {
//据题意做相关修改
scanf("%d", &sum[rt]);
return ;
}
int m = (l+r)>>1;
bulid(lson);
bulid(rson);
PushUp(rt);
}
void update(int p, int add, int l = 1, int r = n, int rt=1) {
if(l==r) {
//据题意做相关修改
sum[rt] += add;
return ;
}
int m = (l+r)>>1;
if(p <= m)
update(p, add, lson);
else
update(p, add, rson);
PushUp(rt);
}
int query(int L,int R,int l = 1,int r = n, int rt=1) {
if(L<=l && r<=R) {
return sum[rt];
}
int m = (l+r)>>1;
int ret = 0;
if(L <= m)
ret = operate(ret, query(L,R,lson));
if(R > m)
ret = operate(ret, query(L,R,rson));
return ret;
}
下面就是杭电的1754,也是第三场比赛的L题:
<a target=_blank href="http://http://vjudge.net/contest/view.action?cid=50696#problem/J">点击打开链接</a>,
题目大大意就是:给定一组学生成绩,要实现能查询其中的最高分并且能够更新其中的某一学生的值。把模板改一改就能完成了。
代码实现:
<pre name="code" class="cpp">#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define lson l, m , rt<<1
#define rson m+1, r, rt << 1 | 1
using namespace std;
int n, m;
int sum[200005<<2];
void build(int l, int r, int rt)
{
if(l == r)
{
scanf("%d", &sum[rt]);
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
sum[rt] = max(sum[rt<<1], sum[rt<<1|1]);
}
void update(int p, int d, int l, int r, int rt)
{
if(l == r)
{
sum[rt] = d;
return ;
}
int m = (l+r)>>1;
if(p<=m) update(p, d, lson);
else update(p, d, rson);
sum[rt] = max(sum[rt<<1], sum[rt<<1|1]);
}
int query(int ll, int rr, int l, int r, int rt)
{
if(ll<=l && rr>=r)
return sum[rt];
int m = (l+r)>>1;
int ans = 0;
if(ll<=m) ans = max(ans, query(ll, rr, lson));
if(rr>m) ans = max(ans, query(ll, rr, rson));
return ans;
}
int main()
{
int ma, a, b;
char c[2];
while(~scanf("%d%d", &n, &m))
{
memset(sum, 0, sizeof(sum));
build(1, n, 1);
for(int i = 0; i<m; i++)
{
scanf("%s%d%d", c, &a, &b);
if(c[0]=='Q')
{
ma = query(a, b, 1, n, 1);
printf("%d\n", ma);
}
if(c[0]=='U')
{
update(a, b, 1, n, 1);
}
}
}
return 0;
}