BZOJ2131: 免费的馅饼
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
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。
【数据规模】
对于100%的数据,1<=w,t[i]<=10^8,1<=n<=100000。
我还是太年轻了被AKC艹爆本来想DP的,看到N<=100000放弃了,结果不会做。。。其实就是DP(我个愣头青f[i]表示接了第i个馅饼的最大值,方程很容易搞出来,但是有个限制条件:f[i]=max( f[j] + v[i] ) | pi-pj | /2<=ti-tj然后化一波柿子:|pi-pj|<=2*ti-2*tj ==== pi-pj<=2*ti-2*tj && pj-pi<=2*ti-2*tj ==== 2*ti-pi>=2*tj-pj && 2*ti+pi>=2*tj+pj然后就变成二维偏序问题了。。排个序树状数组维护一下就OK
//MT_LI #include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; typedef long long ll; int n,w; int lowbit(int x){return x&-x;} ll cc[210000]; void change(int x,ll d){while(x<=n+1){cc[x]=max(cc[x],d);x+=lowbit(x);}} ll getmax(int x){ll ans=0;while(x){ans=max(ans,cc[x]);x-=lowbit(x);}return ans;} struct node{ int x,y;ll v; }a[210000]; int LS[210000]; bool cmp(node a,node b) { if(a.x!=b.x)return a.x<b.x; return a.y<b.y; } int main() { scanf("%d%d",&w,&n); for(int i=1;i<=n;i++) { int t,p; scanf("%d%d%lld",&t,&p,&a[i].v); a[i].x=2*t+p;a[i].y=2*t-p; LS[i]=a[i].y; } sort(a+1,a+1+n,cmp); sort(LS+1,LS+1+n); for(int i=1;i<=n;i++) { ll ans=0ll;int pos=lower_bound(LS+1,LS+n+1,a[i].y)-LS; ans=getmax(pos)+a[i].v; change(pos,ans); } printf("%lld\n",getmax(n+1)); return 0; }
The deepest love I think,later than apart,I will live as you like