洛谷 P3957 跳房子

https://www.luogu.org/problemnew/show/P3957

错误记录:1.没开longlong 2. -inf不够小

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6 #define fi first
 7 #define se second
 8 #define mp make_pair
 9 #define pb push_back
10 typedef long long ll;
11 typedef unsigned long long ull;
12 #define int ll
13 typedef pair<int,int> pii;
14 int n,d,K;
15 pii p[500100];
16 int qq[500100],ql,qr;
17 int an[500100];
18 //an[i]表示i格子最大得分
19 //an[i]=max{an[j]}+s[i],i-r<=j<=i-l
20 bool judge(int ttt)
21 {
22     int l=max(1ll,d-ttt),r=d+ttt;
23     ql=1;qr=0;
24     int ans=-0x3f3f3f3f3f3f3f3f,L,R,i;
25     an[0]=0;
26     for(i=1,L=0,R=-1;i<=n;i++)
27     {
28         while(R+1<i&&p[R+1].fi<=p[i].fi-l)
29         {
30             ++R;
31             while(ql<=qr&&an[qq[qr]]<=an[R])    --qr;
32             qq[++qr]=R;
33         }
34         while(L<i&&p[L].fi<p[i].fi-r)
35         {
36             if(qq[ql]==L)    ++ql;
37             ++L;
38         }
39         an[i]=ql<=qr?an[qq[ql]]+p[i].se:-0x3f3f3f3f3f3f3f3f;
40         ans=max(ans,an[i]);
41     }
42     return ans>=K;
43 }
44 signed main()
45 {
46     int nn,x,y,i;
47     scanf("%lld%lld%lld",&nn,&d,&K);
48     for(i=1;i<=nn;i++)
49     {
50         scanf("%lld%lld",&x,&y);
51         if(!n||x!=p[n].fi)    p[++n].fi=x,p[n].se=y;
52         else    p[n].se=max(p[n].se,y);
53     }
54     int t=0;
55     for(i=1;i<=n;i++)
56         if(p[i].se>0)
57             t+=p[i].se;
58     if(t<K)
59     {
60         puts("-1");
61         return 0;
62     }
63     int l=0,r=1e10,mid;
64     while(l!=r)
65     {
66         mid=l+((r-l)>>1);
67         if(judge(mid))    r=mid;
68         else    l=mid+1;
69     }
70     printf("%lld",l);
71     return 0;
72 }
View Code

 

posted @ 2018-10-20 15:17  hehe_54321  阅读(148)  评论(0编辑  收藏  举报
AmazingCounters.com