线段树单点更新个人总结

1.1.单点更新 hdu2795 Billboard

#include <iostream>
#include <cstdio>
#include <algorithm>
#define lint long long
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
const int maxn = 222222;
int MAX[maxn<<2];
int h, w;
int ans[maxn];
void pushup(int rt)
{
    MAX[rt] = max(MAX[rt<<1], MAX[rt<<1|1]);    
}
void build(int l, int r, int rt)
{
     if (l == r) {MAX[rt] = w; return;}
     int m = (l+r)>>1;
     build(lson);
     build(rson);
     pushup(rt);
}
void update(int ap,int sc, int l, int r, int rt)
{
     if(l == r) 
     {
          MAX[rt] = MAX[rt] - sc;
          ans[ap] = l;
          return;
     }
     int m = (l+r)>>1;
     if(sc <= MAX[rt<<1]) update(ap, sc, lson);
     else update(ap, sc, rson);
     pushup(rt);
}
int n;
int main()
{
    memset(ans, 0, sizeof(ans));
    while(scanf("%d%d%d", &h, &w, &n) != EOF)
    {
       if(h>n) h = n;
       build(1, h, 1);
       int wi;
       for(int i = 0; i < n; i++)
       {
               scanf("%d", &wi);
               if(wi > MAX[1]) ans[i] = -1;
               else update(i, wi, 1, h, 1);
       }
       for(int i = 0; i < n; i++)
         printf("%d\n", ans[i]);
    }
    return 0;
}
1.2.单点更新 hdu1394 Minimum Inversion Number
#include <cstdio>
#include <algorithm>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
const int maxn = 5555;
int sum[maxn<<2];
void pushup(int rt)
{
     sum[rt] = sum[rt<<1]+sum[rt<<1|1];
}
void build(int l ,int r, int rt)
{
     sum[rt] = 0;
     if(l == r)  return;
     int m = (l+r)>>1;
     build(lson);
     build(rson);
}
void update(int p ,int l, int r, int rt)
{
     if(l == r) {sum[rt]++; return;}
     int m = (r+l)>>1;
     if(p <= m) update(p, lson);
     else update(p ,rson);
     pushup(rt);
} 
int query(int L, int R, int l, int r, int rt)
{
    if(L <= l && r <= R) return sum[rt];
    int m = (l+r)>>1;
    int ret = 0;
    if(L <= m) ret += query(L, R, lson);
    if(m < R) ret += query(L, R, rson);
    return ret;
}
int x[maxn];
int n;
int main()
{
    while(scanf("%d", &n) != EOF)
    {
        build(0, n-1, 1);
        int sum = 0;
        for(int i = 0; i < n; i++)
        {
           scanf("%d", &x[i]);
           sum += query(x[i],n-1, 0, n-1, 1);
           update(x[i], 0, n-1, 1);
        }
        int ret = sum;
        for(int i = 0; i < n; i++)
        {
            sum += n-x[i]-x[i]-1;
            ret = min(sum, ret);
        }
        printf("%d\n", ret);
    }
    return 0;
}

1.3.单点更新 hdu 1754 I hate it
#include<cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define mset(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 222222;
int MAX[maxn<<2];

void pushup(int rt)
{
     MAX[rt] = max(MAX[rt<<1], MAX[rt<<1|1]);
}  
void build(int l, int r, int rt)
{
     if(l == r) {scanf("%d", &MAX[rt]); return;}
     int m = (l+r)>>1;
     build(lson);
     build(rson);
     pushup(rt);
}
void update(int p , int sc, int l ,int r, int rt)
{
     if(l == r) { MAX[rt] = sc; return;}
     int m = (l + r)>>1;
     if(p <= m) update(p ,sc, lson);
     else update(p, sc, rson);
     pushup(rt);
}
int query(int L, int R, int l ,int r, int rt)
{
    if(L <= l && r <= R) return MAX[rt];
    int m = (l+r)>>1;
    int ret = -1;
    if(L <= m) ret = max(ret, query(L, R, lson));
    if(m < R) ret = max(ret, query(L, R, rson));
    return ret;
}
int main()
{
    int N, M;
    mset(MAX, 0);
    while(~scanf("%d%d", &N, &M))
    {
       build(1, N, 1);
       while(M--)
       {
          char ch[3];
          int a, b;
          scanf("%s%d%d",ch, &a, &b);
          if(ch[0] == 'Q') printf("%d\n", query(a, b, 1,N, 1));
          else update(a, b, 1, N, 1);
       }
    }
    return 0;
}
1.4.单店更新 hdu1166 敌兵布阵

#include <cstdio>
 
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 55555;
int sum[maxn*3];
void PushUP(int rt) {
	sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
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);
	PushUP(rt);
}
void update(int p,int add,int l,int r,int rt) {
	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,int r,int rt) {
	if (L <= l && r <= R) {
		return sum[rt];
	}
	int m = (l + r) >> 1;
	int ret = 0;
	if (L <= m) ret += query(L , R , lson);
	if (R > m) ret += query(L , R , rson);
	return ret;
}
int main() {
	int T , n;
	scanf("%d",&T);
	for (int cas = 1 ; cas <= T ; cas ++) {
		printf("Case %d:\n",cas);
		scanf("%d",&n);
		build(1 , n , 1);
		char op[10];
		while (scanf("%s",op)) {
			if (op[0] == 'E') break;
			int a , b;
			scanf("%d%d",&a,&b);
			if (op[0] == 'Q') printf("%d\n",query(a , b , 1 , n , 1));
			else if (op[0] == 'S') update(a , -b , 1 , n , 1);
			else update(a , b , 1 , n , 1);
		}
	}
	return 0;
}

1.5.单点更新  poj 2182 lost cows

#include <iostream>
#include <cstdio>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1 
using namespace std;
const int maxn = 8005;
int num[maxn];
int ans[maxn];
int n;
int sum[maxn<<2];
void pushup(int rt)
{
     sum[rt] = sum[rt<<1]+sum[rt<<1|1];
}
void build(int l ,int r, int rt)
{
     if(l == r) { sum[rt] =1; return;}
     int m = (l+r)>>1;
     build(lson);
     build(rson);
     pushup(rt);
}
void update(int p, int ap, int l, int r, int rt)
{
     if(l == r) { sum[rt] = 0; ans[ap] = l; return;}
     int m = (l+r)>>1;
     if(p <= sum[rt<<1]) update(p, ap, lson);
     else update(p-sum[rt<<1], ap, rson);
     pushup(rt);
}

int main()
{
    scanf("%d", &n);
    memset(ans, 0 , sizeof(ans));
    num[1]=0;
    for(int i = 2; i <= n; i++)
    {
       scanf("%d", &num[i]);
    }
    build(1,n,1);
    for(int i = n; i >=1; i--)
    {
            update(num[i]+1,i,1,n,1);
    }
    for(int i = 1; i <= n; i++)
    {
       printf("%d\n", ans[i]);
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值