URAL 1019 Line Painting

本文分享了线段树的基本概念、实现技巧及其在不同题目中的应用案例,包括区间更新、离散化处理等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一看不想别的,,,,就是线段树了啊(非说是二分也可以毕竟是一样的.....)

然后就悲剧了,,,因为我不太会..记得以前做过一道ZOJ的区间更新颜色的题....但是把....忘了


于是重新找题做一下先

HDU1698 just a hook

dota!!!!哈哈.......题意很简单了

主要是打出来个模板

#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>

using namespace std;


 const int MAXN = 100010;
 int sum[MAXN<<2];
 int lazy[MAXN<<2];

 void pushup(int rt)
 {
     sum[rt] = sum[rt<<1] + sum[rt<<1|1];  //gengxinhe,,ba zishu de jiashanglai
 }

 void pushdown(int rt, int x)//最大的那一块的最右边开始
 {
     if(lazy[rt] != -1)
     {
         lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];//标记值下放
         sum[rt<<1] = (x-(x>>1))*lazy[rt];//左子树加上标记值
         sum[rt<<1|1] = (x>>1)*lazy[rt];//右子树
         lazy[rt] = -1;
     }
 }

 void creat(int l, int r, int rt)
 {
     lazy[rt] = -1, sum[rt] = 1;//chushihuasuoyoujiedian sum genjutiyi shi -1
     if(l == r) return;
     int mid = (l+r)>>1;
     creat(l, mid, rt<<1);//jian zuoyou zishu
     creat(mid+1, r, rt<<1|1);
     pushup(rt);
 }

 void modify(int l, int r, int x, int L, int R, int rt)
 {
     if(l <= L && r >= R) //ruguo yaogengxinde ba nage fugaile ,nage jiuzhijie jiashang nayiduan dehe jiuhao
     {
         lazy[rt] = x;
         sum[rt] = x*(R-L+1);
         return;
     }
     pushdown(rt, R-L+1);//jiedianbiaoji xiangxiachuanti
     int mid = (L+R)>>1;
     if(l <= mid) modify(l, r, x, L, mid, rt<<1);  //如果在左子树有重合那就去
     if(r > mid) modify(l, r, x, mid+1, R, rt<<1|1);//如果在右子树
     pushup(rt); //gengxin sum
 }

 int main()
 {
     int i, j, k = 0;
     int n, T, q;
     int x, y, w;
     while(scanf("%d", &T) != EOF)
     while(T--)
     {
         scanf("%d %d", &n, &q);
         creat(1, n, 1);  //jianshu

         while(q--)
         {
             scanf("%d %d %d", &x, &y, &w);
             modify(x, y, w, 1, n, 1); //jiushi update   
         }
         printf("Case %d: The total value of the hook is %d.\n", ++k, sum[1]);
     }
     return 0;
 }

效率不仅在于二分更在于不是一条指令就执行一次而是加一起来执行


zoj 1610 color ~成段更新

    #include<iostream>  
    #include<cstdio>  
    #include<cstring>  
    #define mem(str,x) memset(str,(x),sizeof(str))  
    #define FOR(i,s,t) for(int i=(s); i<(t); ++i)  
    #define FF(i,n) for(int i=0; i<(n); ++i)  
    #define mid ((left+right)>>1)  
    #define len (right-left+1)  
    #define lson rt<<1, left, m  
    #define rson rt<<1|1, m+1, right  
    #define STOP puts("Stop Here~");  
    using namespace std;  
    const int MAXN = 8005;  
    int n,col[MAXN<<2],vis[MAXN<<2],ans[MAXN<<2];  
      
    inline void push_down(int rt){  
        if(col[rt] != -1){  
            col[rt<<1] = col[rt<<1|1] = col[rt];  
            col[rt] = -1;  
        }  
    }  
    void update(int rt,int left,int right,int l,int r,int data){  
        if(l<=left && right<=r){  
            col[rt] = data;  
            return;  
        }  
        if(col[rt] == data) return;  
        if(col[rt]!=-1)push_down(rt);  
        int m = mid;  
        if(l <= m)update(lson,l,r,data);  
        if(r > m)update(rson,l,r,data);  
    }  
    void query(int rt,int left,int right){  
        if(col[rt]>=0){  
            for(int i=left; i<=right; ++i)  
                vis[i] = col[rt];  
            return;  
        }  
        if(left!=right && col[rt] == -1){  
            int m = mid;  
            query(lson);  
            query(rson);  
        }  
    }  
      
    int main(){  
        int a,b,c;  
        while(~scanf("%d",&n)){  
            memset(col,-1,sizeof(col));  
            for(int i=0; i<n; ++i){  
                scanf("%d%d%d",&a,&b,&c);  
                if(a>=b)continue;  
                update(1,1,8000,a+1,b,c);  
            }  
      
            mem(vis,-1);   
            query(1,1,8000);  
            int i = 1;  
      
            mem(ans,0);  
            while(i<MAXN){  
                int color=vis[i], j=i+1;  
                if(color==-1){++i; continue;}  
                while(vis[j]!=-1 && vis[j]==color && j<MAXN) ++j;  
                ++ans[color];  
                i=j;  
            }  
            for(int i=0; i<MAXN; ++i)if(ans[i])  
                printf("%d %d\n",i,ans[i]);  
            puts("");   
        }  
        return 0;  
    }
做两题之后觉得好爽啊,,,,,,而且效率也很高,,,,,最然代码都参考了别人的但是明白了很多东西.......


所以再来几道!!!     POJ3468

#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
#define N 111111  
#define LL long long  
#define lson l,m,rt<<1  
#define rson m+1,r,rt<<1|1  
      
    LL add[N<<2];  
    LL sum[N<<2];  
      
    void PushUP(int rt)  
    {  
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];  
    }  
      
    void PushDown(int rt,int m)  
    {  
        if(add[rt])  
        {  
            add[rt<<1]+=add[rt];  
            add[rt<<1|1]+=add[rt];  
            sum[rt<<1]+=(m-(m>>1))*add[rt];  
            sum[rt<<1|1]+=(m>>1)*add[rt];  
            add[rt]=0;  
        }  
    }  
      
    void Build(int l,int r,int rt)  
    {  
        add[rt]=0;  
        if(l==r)  
        {  
            scanf("%I64d",&sum[rt]);  
            return;  
        }  
        int m=(l+r)>>1;  
        Build(lson);  
        Build(rson);  
        PushUP(rt);  
    }  
      
    void Update(int L,int R,int c,int l,int r,int rt)  
    {  
        if(L<=l&&R>=r)  
        {  
            add[rt]+=c;  
            sum[rt]+=(LL)c*(r-l+1);  
            return;  
        }  
        PushDown(rt,r-l+1);  
        int m=(l+r)>>1;  
        if(L<=m)  
            Update(L,R,c,lson);  
        if(R>m)  
            Update(L,R,c,rson);  
        PushUP(rt);  
    }  
      
    LL Query(int L,int R,int l,int r,int rt)  
    {  
        if(L<=l&&R>=r)  
            return sum[rt];  
        PushDown(rt,r-l+1);  
        int m=(l+r)>>1;  
        LL ret=0;  
        if(L<=m)   ret+=Query(L,R,lson);  
        if(R>m)    ret+=Query(L,R,rson);  
        return ret;  
    }  
      
    int main()  
    {  
        int m,n;  
        scanf("%d%d",&n,&m);  
        Build(1,n,1);  
        while(m--)  
        {  
            char s[5];  
            int a,b,c;  
            scanf("%s",s);  
            if(s[0]=='Q')  
            {  
                scanf("%d%d",&a,&b);  
                printf("%I64d\n",Query(a,b,1,n,1));  
            }  
            else  
            {  
                scanf("%d%d%d",&a,&b,&c);  
                Update(a,b,c,1,n,1);  
            }  
        }  
        return 0;  
    } 

恩....还需要再练几题的线段树,,,,,先做URAL的这个吧.......别的以后再说把.......

/*这题二分暴力可以过...*/

还有这题数据特别大所以需要离散化处理...........

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include<bits/stdc++.h>
#include <string.h>
using namespace std;
#define lson l,m,n<<1
#define rson m+1,r,n<<1|1
const int N=1e5;
int s[N<<2];
void pushdown(int n)
{
    if(~s[n])
    {
        s[n<<1]=s[n<<1|1]=s[n];
        s[n]=-1;
    }
}
void build(int l, int r, int n)
{
    if(l==r)
    {
        s[n]=0;
        return ;
    }
    s[n]=-1;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}
void update(int L,int R,int c,int l,int r,int n)
{
    if(L==l&&R==r)
    {
        s[n]=c;
        return ;
    }
    pushdown(n);
    int m=(l+r)>>1;
    if(R<=m) update(L,R,c,lson);
    else if(L>m) update(L,R,c,rson);
    else update(L,m,c,lson),update(m+1,R,c,rson);
}
int query(int pos,int l,int r,int n)
{
    if(l==r) return s[n];
    pushdown(n);
    int m=(l+r)>>1;
    if(pos<=m) return query(pos,lson);
    else return query(pos,rson);
}
int X[N];
struct op
{
    int L,R;
    char col[3];
}o[N];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%1s",&o[i].L,&o[i].R,o[i].col);
            X[++cnt]=o[i].L<<1;
            X[++cnt]=o[i].L<<1|1;
            X[++cnt]=o[i].R<<1;
            X[++cnt]=o[i].R<<1|1;
        }
        X[++cnt]=0;
        X[++cnt]=1;
        X[++cnt]=2e9;
        X[++cnt]=2e9+1;
        sort(X+1,X+1+cnt);
        int k=1;
        for(int i=2;i<=cnt;i++)
        {
            if(X[i]!=X[i-1]) X[++k]=X[i];
        }
        build(1,k,1);
        for(int i=1;i<=n;i++)
        {
            int L=lower_bound(X+1,X+1+k,o[i].L<<1|1)-X;
            int R=lower_bound(X+1,X+1+k,o[i].R<<1)-X;
            int c=o[i].col[0]=='w'?0:1;
            update(L,R,c,1,k,1);
        }
        pair<int,int>ans;
        int aaa=0;
        for(int i=1;i<=k;i++)
        {
            if(query(i,1,k,1)==1) continue;
            int j=i;
            while(j<=k&&query(j,1,k,1)==0) ++j;
            int now=(X[j-1]>>1)-(X[i-1]>>1);
            if(now>aaa)
            {
                aaa=now;
                ans=make_pair(X[j-1]>>1,X[i-1]>>1);
            }
            i=j;
        }
        printf("%d %d\n",ans.second,ans.first);
    }
    return 0;
}

离散化处理好烦,,,现在也不太会。。。。。




1. 用户与身体信息管理模块 用户信息管理: 注册登录:支持手机号 / 邮箱注册,密码加密存储,提供第三方快捷登录(模拟) 个人资料:记录基本信息(姓名、年龄、性别、身高、体重、职业) 健康目标:用户设置目标(如 “减重 5kg”“增肌”“维持健康”)及期望周期 身体状态跟踪: 体重记录:定期录入体重数据,生成体重变化曲线(折线图) 身体指标:记录 BMI(自动计算)、体脂率(可选)、基础代谢率(根据身高体重估算) 健康状况:用户可填写特殊情况(如糖尿病、过敏食物、素食偏好),系统据此调整推荐 2. 膳食记录与食物数据库模块 食物数据库: 基础信息:包含常见食物(如米饭、鸡蛋、牛肉)的名称、类别(主食 / 肉类 / 蔬菜等)、每份重量 营养成分:记录每 100g 食物的热量(kcal)、蛋白质、脂肪、碳水化合物、维生素、矿物质含量 数据库维护:管理员可添加新食物、更新营养数据,支持按名称 / 类别检索 膳食记录功能: 快速记录:用户选择食物、输入食用量(克 / 份),系统自动计算摄入的营养成分 餐次分类:按早餐 / 午餐 / 晚餐 / 加餐分类记录,支持上传餐食照片(可选) 批量操作:提供常见套餐模板(如 “三明治 + 牛奶”),一键添加到记录 历史记录:按日期查看过往膳食记录,支持编辑 / 删除错误记录 3. 营养分析模块 每日营养摄入分析: 核心指标计算:统计当日摄入的总热量、蛋白质 / 脂肪 / 碳水化合物占比(按每日推荐量对比) 微量营养素分析:检查维生素(如维生素 C、钙、铁)的摄入是否达标 平衡评估:生成 “营养平衡度” 评分(0-100 分),指出摄入过剩或不足的营养素 趋势分析: 周 / 月营养趋势:用折线图展示近 7 天 / 30 天的热量、三大营养素摄入变化 对比分析:将实际摄入与推荐量对比(如 “蛋白质摄入仅达到推荐量的 70%”) 目标达成率:针对健
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值