2131: 免费的馅饼
Description
Input
第一行是用空格隔开的二个正整数,分别给出了舞台的宽度W(1到10^8之间)和馅饼的个数n(1到10^5)。 接下来n行,每一行给出了一块馅饼的信息。由三个正整数组成,分别表示了每个馅饼落到舞台上的时刻t[i](1到10^8秒),掉到舞台上的格子的编号p[i](1和w之间),以及分值v[i](1到1000之间)。游戏开始时刻为0。输入文件中同一行相邻两项之间用一个空格隔开。输入数据中可能存在两个馅饼的t[i]和p[i]都一样。
Output
一个数,表示游戏者获得的最大总得分。
Sample Input
3 4
1 2 3
5 2 3
6 3 4
1 1 5
Sample Output
12
【数据规模】
对于100%的数据,1<=w,t[i]<=10^8,1<=n<=100000。
【解题报告】
某次比赛的题
代码如下:
/**************************************************************
Problem: 2131
User: onepointo
Language: C++
Result: Accepted
Time:316 ms
Memory:3948 kb
****************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define M 100002
#define low(x) (x&(-x))
int W,n,ans;
int d[M],f[M],tmp[M];
struct Data
{
int x,y,t,p,v;
bool friend operator < (Data a,Data b)
{return (a.x==b.x)?a.y>b.y:a.x<b.x;}
}a[M];
int get(int x)
{
int mx=0;
for(;x;x-=low(x)) mx=max(mx,d[x]);
return mx;
}
void add(int x,int data)
{
for(;x<=n+1;x+=low(x))
d[x]=max(d[x],data);
}
int main()
{
scanf("%d%d",&W,&n);
a[0].x=a[0].y=a[0].t=-W;
for(int i=1;i<=n;++i)
{
scanf("%d%d%d",&a[i].t,&a[i].p,&a[i].v);
a[i].t<<=1;
a[i].x=a[i].t+a[i].p;
a[i].y=a[i].t-a[i].p;
}
sort(a,a+n+1);
for(int i=0;i<=n;++i) tmp[i]=a[i].y;
sort(tmp,tmp+n+1);
for(int i=0;i<=n;++i) a[i].y=lower_bound(tmp,tmp+n+1,a[i].y)-tmp+1;
for(int i=1;i<=n;++i)
{
f[i]=a[i].v+get(a[i].y);
add(a[i].y,f[i]);
}
for(int i=1;i<=n;++i) ans=max(ans,f[i]);
printf("%d",ans);
return 0;
}