Surf(树状数组维护最大值)

Now that you’ve come to Florida and taken up surfing, you love it! Of course, you’ve realized that
if you take a particular wave, even if it’s very fun, you may miss another wave that’s just about
to come that’s even more fun. Luckily, you’ve gotten excellent data for each wave that is going to
come: you’ll know exactly when it will come, how many fun points you’ll earn if you take it, and
how much time you’ll have to wait before taking another wave. (The wait is due to the fact that
the wave itself takes some time to ride and then you have to paddle back out to where the waves
are crashing.) Obviously, given a list of waves, your goal will be to maximize the amount of fun
you could have.
Consider, for example, the following list of waves:
Minute Fun points Wait time
2 80 9
8 50 2
10 40 2
13 20 5
In this example, you could take the waves at times 8, 10 and 13 for a total of 110 fun points. If
you take the wave at time 2, you can’t ride another wave until time 11, at which point only 20 fun
points are left for the wave at time 13, leaving you with a total of 100 fun points. Thus, for this
input, the correct answer (maximal number of fun points) is 110.
Given a complete listing of waves for the day, determine the maximum number of fun points
you could earn.
Input
The first line of input contains a single integer n (1 ≤ n ≤ 300,000), representing the total number
of waves for the day. The ith line (1 ≤ i ≤ n) that follows will contain three space separated
integers: mi
, fi
, and wi
, (1 ≤ mi
, fi
, wi ≤ 106
), representing the time, fun points, and wait time
of the ith wave, respectively. You can ride another wave occurring at exactly time mi + wi after
taking the ith wave. It is guaranteed that no two waves occur at the same time. The waves may
not be listed in chronological order.
2015 Pacific Northwest Region Programming Contest—Division 2 17
Output
Print, on a single line, a single integer indicating the maximum amount of fun points you can get
riding waves.
Sample Input Sample Output
4
8 50 2
10 40 2
2 80 9
13 20 5
110
Sample Input Sample Output
10
2079 809484 180
8347 336421 2509
3732 560423 483
2619 958859 712
7659 699612 3960
7856 831372 3673
5333 170775 1393
2133 989250 2036
2731 875483 10
7850 669453 842
3330913

对结束时间进行从小到大排序。
结束时间=开始时间+持续时间。
树状数组里维护的是结束时间的最大值。
对于每一个开始时间,找到开始时间的最大值,然后加上当前的权值,作为结束时间的值进行维护,如果比原来的要大,那么就更新。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define max(a,b)   (a>b?a:b)
#define min(a,b)   (a
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
#define memset(a)  memset(a,0,sizeof(a))
#define X (sqrt(5)+1)/2.0  //Wythoff
#define Pi acos(-1)
#define e  2.718281828459045
using namespace std;
typedef long long int LL;
const int MAXL(1e6);
const int INF(0x3f3f3f3f);
const int mod(1e9+7);
int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
LL t[2*MAXL+50];
int maxY;
struct node
{
    int st,ed,power;
}s[300000+50];
bool cmp(struct node p,struct node q)
{
    if(p.ed==q.ed)
        return p.streturn p.edint lowbit(int k)
{
    return k&(-k);
}
void Update(int i,LL v)
{
    while(i<=maxY)
    {
        t[i]=max(t[i],v);
        i+=lowbit(i);
    }
}
LL Getsum(int i)
{
    LL ans=0;
    while(i>0)
    {
        ans=max(ans,t[i]);
        i-=lowbit(i);
    }
    return ans;
}
int main()
{
    memset(t);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        s[i].st=x;
        s[i].ed=x+z;
        s[i].power=y;
    }
    sort(s+1,s+n+1,cmp);
    maxY=s[n].ed;
    for(int i=1;i<=n;i++)
    {
        LL temp=Getsum(s[i].st);
        temp+=s[i].power;
        Update(s[i].ed,temp);
    }
    cout<

你可能感兴趣的:(线段树/树状数组,无处可归的题)