免费的馅饼 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 }

猜你喜欢

转载自www.cnblogs.com/letlifestop/p/10354638.html