XVIII Open Cup named after E.V. Pankratiev Stage 5: Eastern Grand Prix, XI Vekua Cup, J

Problem J. JokeCoin
Input file: standard input
Output file: standard output
Time limit: 2 seconds
Memory limit: 256 mebibytes
The JokeCoin is the new cryptocurrency.
Vasya is planning to start working with this currency. People who are mining this currency receive the
schedule of the data blocks for the day.For each data block Vasya knows time interval to process this data
block, and the reward in JokeCoins for successful mining of this block (i.e. when block was processed at
given interval without interruptions). Vasya can freely select the blocks to process; mining of the next
selected block may start at the same second, when mining of current block is finished.
Vasya don’t have enough resources to process more than one block simultaneously. Additionally, per
each second used for mining, Vasya pays fixed amount of JokeCoins to the power company.
Vasya wants to know, if he will have any profit for work with JokerCoin, so he asks you to write the
program which can calculate maximum expected profit for Vasya using given schedule.
Input
First line contains two integers N and C (1 ≤ N < 86 400, 0 ≤ C ≤ 1000) — number of blocks in the
schedule and amount of JokeCoins Vasya pays to the power company per second of mining. Next N lines
describe blocks.
Each of those lines contain starting time of mining and ending time of mining in the format HH:MM:SS
between 00:00:00 and 23:59:59, inclusively, difference between starting and ending time for one block
is atleast 1 second and the bonus P (0 ≤ P ≤ 105
) in JokeCoins for successful mining of this data block.
Output
Print one integer — maximal possible profit, or 0, if profit is zero or negative.
Example
standard input standard output
4 0
03:00:00 10:10:00 20
01:00:00 02:30:00 50
16:10:00 19:00:00 100
02:30:00 22:00:00 200
250
3 1
16:59:00 17:00:00 100
01:01:01 01:01:11 20
12:00:00 13:00:00 3601
51
4 10
00:00:05 00:01:55 1100
00:00:10 00:00:21 100
00:01:50 00:02:00 80
23:59:00 23:59:05 40
0

考虑用树状数组维护某一时间点所能得到的最大值;
按左端点排序即可;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
using namespace std;
#define maxn 200005
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
typedef long long  ll;
typedef unsigned long long ull;
#define ms(x) memset(x,0,sizeof(x))
const long long int mod = 1e9 + 7;


inline int read()
{
    int x = 0, k = 1; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-')k = -1; c = getchar(); }
    while (c >= '0' && c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return x * k;
}

struct node
{
    int st,ed,w;
    bool operator <(const node&rhs)const
    {
        return st<rhs.st;
    }
}a[maxn];

ll lowbit(ll x)
{
    return x&-x;
}

ll ans,f[maxn];

void add(ll x,ll k)
{
    while(x<maxn){
        f[x]=max(f[x],k);x+=lowbit(x);
    }
}

ll query(int x)
{
    ll res=0;
    while(x){
        res=max(res,f[x]);x-=lowbit(x);
    }
    return res;
}

int main()
{
    //ios::sync_with_stdio(false);
    int n,c;cin>>n>>c;
    for(int i=1;i<=n;i++){
        int x,y,z;
        scanf("%d:%d:%d",&x,&y,&z);
        a[i].st=x*3600+y*60+z+7;
        scanf("%d:%d:%d",&x,&y,&z);
        a[i].ed=x*3600+y*60+z+7;
        z=read();
        a[i].w=z-(a[i].ed-a[i].st)*c;
    }
    sort(a+1,a+1+n);
    for(int  i=1;i<=n;i++){
        ll tmp=query(a[i].st)+a[i].w;
        ans=max(ans,tmp);
        add(a[i].ed,tmp);
    }
    cout<<ans<<endl;
}

猜你喜欢

转载自blog.csdn.net/qq_40273481/article/details/81841203