您的位置:首页 > 其它

日程管理

2016-03-27 14:45 176 查看

日程管理

时间限制: 2 Sec 内存限制: 512 MB

题目描述

幽吞是幻想乡中一个非常有地位的人。她日理万机,事务繁多,感到自己已经快理不过来了。于是她决定开发一个日程管理软件来帮组自己管理任务。

对于每个任务i有一个对应的截止日期ti以及收益pi,表示若幽香能在不晚于第ti天完成这个任务,使可以得到pi的收益。幽香办事的能力非常强,任何任务部可以用恰好一天时间做完。但由于任务实在太多了,有时候并不能完成所有任务,于是幽香会想要知道这个情况下,完成任务可以给她带来最大的累积收益是多少。

由于幻想乡的人们十分善变,任务总是不断发生肴变化。幽香希望这个管理软件还能够支持插入一个任务,和删除一个任务的操作。

具体的说.幽香希t}支持以下7个操作:

1. ADD t p:表示新添一个截止日期为t,收益为p的任务。

2. DEL t p:表示删除一个截止日期为t,收益为p的任务。如果有多个这

样的任务,只删除一个。数据保证这样的任务一定存在。

在每次操作执行完毕后,你都甲需要输出能够完成的任务的最大收益和。

幽香一共有T天需要安排,从第1天到第T天,你能帮助她写出这个高效率的软件吗?

输入

第一行有两个正整数T和Q,表示天数和操作的个数。

接下来Q行,其中第i行表示第i个操作,形式为ADD t p或DEL t p,其具体意义如体面所述。

输出

要求对于每一次操作,输出一个整数在执行完该后幽香能获得的最大收益和。

样例输入

5 10

ADD 1 5811

ADD 3 5032

DEL 3 5032

ADD 3 5550

ADD 5 3486

DEL 1 5811

DEL 3 5550

ADD 4 5116

ADD 3 9563

ADD 5 94

样例输出

5811

10843

5811

11361

14847

9036

3486

8602

18165

18259

数据范围

T<=300000,Q<=300000

来源

ctsc2015 day2

题解

幽香。。陈老师的题。。

假设只有一组询问,考虑贪心,将任务按照p排序,从大到小插入即可。

所以我们可以拿2棵线段树分别维护已经插入的和暂时未插入的任务。

为了方便操作,再写一棵线段树表示每个时间点能否再增加任务。

对于每次ADD操作,先在插入的t后面寻找一个最左边的不能增加任务的位置。如果找不到则显然直接加入这个任务。若找到了,则在【1,这个位置】这段区间内寻找最小值,并和这次操作的t比较即可。

对于每次DEL操作,如果没有插入,则直接删除即可。

考虑已经插入的情况,则显然应该寻找最后一个不能增加任务的位置,并选择t在这个位置之后的节点中p最小的来替代。

以上题解来自本蒟蒻口胡。

要看正常的题解的话去找cls的ppt。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<algorithm>
#define inf 1050000000
#define N 300005
using namespace std;
int n,Q,ans;
struct node{int minn,pos;};
struct info{int minn,tag;};

class seg_tree_2
{
node merge(node a,node b)
{
if(a.minn<b.minn)return a;
return b;
}
public:
node t[N*4];multiset<int>q
;
void build(int x,int l,int r)
{
if(l==r)
{
t[x].minn=inf;t[x].pos=l;
q[l].insert(inf);return;
}
int mid=l+r>>1,lc=x<<1,rc=lc+1;
build(lc,l,mid);build(rc,mid+1,r);
t[x]=merge(t[lc],t[rc]);
}
void insert(int x,int l,int r,int ti,int p)
{
if(l==r)
{
t[x].minn=min(t[x].minn,p);
q[l].insert(p);return;
}
int mid=l+r>>1,lc=x<<1,rc=lc+1;
if(ti<=mid)insert(lc,l,mid,ti,p);
else insert(rc,mid+1,r,ti,p);
t[x]=merge(t[lc],t[rc]);
}
bool erase(int x,int l,int r,int ti,int p)
{
if(t[x].minn>p)return false;
if(l==r)
{
q[l].erase(q[l].find(p));
t[x].minn=*q[l].begin();
return true;
}
int mid=l+r>>1,lc=x<<1,rc=lc+1,res;
if(ti<=mid)res=erase(lc,l,mid,ti,p);
else res=erase(rc,mid+1,r,ti,p);
t[x]=merge(t[lc],t[rc]);
return res;
}
node qry(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)return t[x];
int mid=l+r>>1,lc=x<<1,rc=lc+1,res=0;
if(qr<=mid)return qry(lc,l,mid,ql,qr);
if(ql>mid)return qry(rc,mid+1,r,ql,qr);
return merge(qry(lc,l,mid,ql,qr),qry(rc,mid+1,r,ql,qr));
}
}T1,T2;

class seg_tree
{
void pushdown(int x)
{
if(!t[x].tag)return;
int lc=x<<1,rc=lc+1;
t[lc].minn+=t[x].tag;t[lc].tag+=t[x].tag;
t[rc].minn+=t[x].tag;t[rc].tag+=t[x].tag;
t[x].tag=0;
}
void update(int x)
{
int lc=x<<1,rc=lc+1;
t[x].minn=min(t[lc].minn,t[rc].minn);
}
public:
info t[N*4];
void build(int x,int l,int r)
{
t[x].minn=l;t[x].tag=0;
if(l==r)return;
int mid=l+r>>1,lc=x<<1,rc=lc+1;
build(lc,l,mid);build(rc,mid+1,r);
}
void modify(int x,int l,int r,int ql,int qr,int val)
{
if(ql<=l&&r<=qr){t[x].minn+=val;t[x].tag+=val;return;}
int mid=l+r>>1,lc=x<<1,rc=lc+1;
pushdown(x);
if(ql<=mid)modify(lc,l,mid,ql,qr,val);
if(qr>mid)modify(rc,mid+1,r,ql,qr,val);
update(x);
}
int find_l(int x,int l,int r,int pos)
{
if(t[x].minn)return 0;
if(l==r)return l;
int mid=l+r>>1,lc=x<<1,rc=lc+1,tmp;
pushdown(x);
if(pos<=mid){if(tmp=find_l(lc,l,mid,pos))return tmp;}
return find_l(rc,mid+1,r,pos);
}
int find_r(int x,int l,int r)
{
if(t[x].minn)return 0;
if(l==r)return l;
pushdown(x);
int mid=l+r>>1,lc=x<<1,rc=lc+1,tmp;
if(tmp=find_r(rc,mid+1,r))return tmp;
return find_r(lc,l,mid);
}
}T;

int main()
{
int ti,p;char s[5];
scanf("%d%d",&n,&Q);
T.build(1,1,n);T1.build(1,1,n);T2.build(1,1,n);
while(Q--)
{
scanf(" %s%d%d",s,&ti,&p);
if(s[0]=='A')
{
int pos=T.find_l(1,1,n,ti);
if(!pos)
{
ans+=p;
T1.insert(1,1,n,ti,p);
T.modify(1,1,n,ti,n,-1);
}
else
{
node x=T1.qry(1,1,n,1,pos);
if(p>x.minn)
{
ans+=p-x.minn;
T1.erase(1,1,n,x.pos,x.minn);
T.modify(1,1,n,x.pos,n,1);
T2.insert(1,1,n,x.pos,-x.minn);
T1.insert(1,1,n,ti,p);
T.modify(1,1,n,ti,n,-1);
}
else T2.insert(1,1,n,ti,-p);
}
}
else
{
if(!T2.erase(1,1,n,ti,-p))
{
ans-=p;
T1.erase(1,1,n,ti,p);
T.modify(1,1,n,ti,n,1);
int pos=T.find_r(1,1,n);
node x=T2.qry(1,1,n,pos+1,n);
if(x.minn<=0)
{
ans-=x.minn;
T2.erase(1,1,n,x.pos,x.minn);
T1.insert(1,1,n,x.pos,-x.minn);
T.modify(1,1,n,x.pos,n,-1);
}
}
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: