免费的馅饼 HYSBZ - 2131 (树状数组维护二维偏序)
题目链接:https://cn.vjudge.net/problem/HYSBZ-2131
题目大意:中文题目
具体思路:对于任意的两个位置,posA和posB,我们可以如下推导。
|posA-posB|<=2*(tA-tB)
2*tB-2*tA<=posA-posB<=2*tB-2*tA.
2*tA+posA>=2*tB+posB || 2*tA -pos A > = 2*tB-posB.(注意这个地方,只要有一个满足就可以了)
然后我们对2*tA+posA进行排序,每一次询问当当前能到达的最远的,这一段的最大值就可以了。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 const int maxn = 1e5+5; 5 struct node 6 { 7 int w1,w2,val; 8 bool friend operator < (node t1,node t2) 9 { 10 if(t1.w1==t2.w1) 11 return t1.w2<t2.w2; 12 return t1.w1<t2.w1; 13 } 14 } q[maxn]; 15 int a[maxn],ans[maxn],sz,c[maxn]; 16 int lowbit(int t) 17 { 18 return t&(-t); 19 } 20 int query(int t) 21 { 22 int maxx=0; 23 for(int i=t; i; i-=lowbit(i)) 24 { 25 maxx=max(maxx,c[i]); 26 } 27 return maxx; 28 } 29 void update(int pos,int val) 30 { 31 for(int i=pos; i<=sz; i+=lowbit(i)) 32 { 33 c[i]=max(c[i],val); 34 } 35 } 36 int main() 37 { 38 int n,m,t,p; 39 scanf("%d %d",&n,&m); 40 for(int i=1; i<=m; i++) 41 { 42 scanf("%d %d %d",&t,&p,&q[i].val); 43 q[i].w1=2*t-p; 44 q[i].w2=2*t+p; 45 } 46 sort(q+1,q+m+1); 47 for(int i=1; i<=m; i++) 48 { 49 a[i]=q[i].w2; 50 } 51 sort(a+1,a+m+1);//注意离散化的时候要进行排序 52 sz=unique(a+1,a+m+1)-a-1; 53 for(int i=1; i<=m; i++) 54 { 55 q[i].w2=lower_bound(a+1,a+sz+1,q[i].w2)-a; 56 ans[i]=query(q[i].w2)+q[i].val; 57 update(q[i].w2,ans[i]); 58 } 59 int maxx=0; 60 for(int i=1; i<=m; i++) 61 { 62 maxx=max(maxx,ans[i]); 63 } 64 printf("%d\n",maxx); 65 return 0; 66 }