URAL 2014 Zhenya moves from parents --线段树

本文介绍了一个儿子使用信用卡并定期汇报收支情况的问题,通过离散时间更新负债的方法,利用数据结构实现高效计算当前信用卡最大负债。

题意:儿子身无分文出去玩,只带了一张他爸的信用卡,当他自己现金不足的时候就会用信用卡支付,然后儿子还会挣钱,挣到的钱都是现金,也就是说他如果有现金就会先花现金,但是有了现金他不会还信用卡的钱。他每花一次钱和挣一次钱都会给他爸发一条短信,告诉他挣/花的钱和时间,但是给出的短信顺序时间可能不是按顺序来的,然后他爸要根据现有的短信信息推测信用卡现在的负债是多少。

解法: 因为挣的钱或花的钱都只影响后面时间的负债,时间离散,每加入一个值,都更新这个pos到n的所有值,然后整个时间最小的值就是答案。结果与0取个最小值就可以了。但是一直不太了解这个原理,求大神解释。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define lll __int64
using namespace std;
#define N 100017

lll Min[4*N],mark[4*N],b[N];
struct node{
    lll val,tim;
}a[N];

void pushup(int rt) { Min[rt] = min(Min[rt<<1],Min[rt<<1|1]); }
void pushdown(int l,int r,int rt)
{
    if(mark[rt])
    {
        mark[rt<<1] += mark[rt];
        mark[rt<<1|1] += mark[rt];
        Min[rt<<1] += mark[rt];
        Min[rt<<1|1] += mark[rt];
        mark[rt] = 0;
    }
}

void build(int l,int r,int rt)
{
    Min[rt] = mark[rt] = 0;
    if(l == r) return;
    int mid = (l+r)/2;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    pushup(rt);
}

void update(int l,int r,int aa,int bb,lll val,int rt)
{
    if(aa <= l && bb >= r)
    {
        Min[rt] += val;
        mark[rt] += val;
        return;
    }
    pushdown(l,r,rt);
    int mid = (l+r)/2;
    if(aa <= mid) update(l,mid,aa,bb,val,rt<<1);
    if(bb > mid)  update(mid+1,r,aa,bb,val,rt<<1|1);
    pushup(rt);
}

lll GetTime()
{
    int date,month,hour,minu;
    scanf("%d.%d %d:%d",&date,&month,&hour,&minu);
    return (lll)month*31LL*24*60 + date*24LL*60 + 60LL*hour + minu;
}

int main()
{
    int n,i,j;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%I64d",&a[i].val);
        a[i].tim = GetTime();
        b[i] = a[i].tim;
    }
    sort(b+1,b+n+1);
    build(1,n+10,1);
    for(i=1;i<=n;i++)
    {
        lll pos = lower_bound(b+1,b+n+1,a[i].tim)-b;
        update(1,n+10,pos,n,a[i].val,1);
        printf("%I64d\n",min(0LL,Min[1]));
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/whatbeg/p/4107242.html

乐播投屏是一款简单好用、功能强大的专业投屏软件,支持手机投屏电视、手机投电脑、电脑投电视等多种投屏方式。 多端兼容与跨网投屏:支持手机、平板、电脑等多种设备之间的自由组合投屏,且无需连接 WiFi,通过跨屏技术打破网络限制,扫一扫即可投屏。 广泛的应用支持:支持 10000+APP 投屏,包括综合视频、网盘与浏览器、美韩剧、斗鱼、虎牙等直播平台,还能将央视、湖南卫视等各大卫视的直播内容一键投屏。 高清流畅投屏体验:腾讯独家智能音画调校技术,支持 4K 高清画质、240Hz 超高帧率,低延迟不卡顿,能为用户提供更高清、流畅的视觉享受。 会议办公功能强大:拥有全球唯一的 “超级投屏空间”,扫码即投,无需安装。支持多人共享投屏、远程协作批注,PPT、Excel、视频等文件都能流畅展示,还具备企业级安全加密,保障会议资料不泄露。 多人互动功能:支持多人投屏,邀请好友加入投屏互动,远程也可加入。同时具备一屏多显、语音互动功能,支持多人连麦,实时语音交流。 文件支持全面:支持 PPT、PDF、Word、Excel 等办公文件,以及视频、图片等多种类型文件的投屏,还支持网盘直投,无需下载和转格式。 特色功能丰富:投屏时可同步录制投屏画面,部分版本还支持通过触控屏或电视端外接鼠标反控电脑,以及在投屏过程中用画笔实时标注等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值