题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan

题解:看了题之后觉得肯定是DP+优化,因为昨天刚水了一道线段树优化DP的题,所以又想到线段树上去了。。。

        具体做法:

        我维护了一个单调递增的f,显然若i<j并且f[i]>f[j],那么f[j]就可以不用

        然后我们要找寻>=a[i]的就是连续的一段了,就可以用线段树来查询f[j]-s[j]的最大值了

        然后 n*logn 水过,居然拿下了first blood

代码:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 250000
14 #define maxm 500+100
15 #define eps 1e-10
16 #define ll long long
17 #define pa pair<int,int>
18 #define for0(i,n) for(int i=0;i<=(n);i++)
19 #define for1(i,n) for(int i=1;i<=(n);i++)
20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
22 #define mod 1000000007
23 using namespace std;
24 inline int read()
25 {
26     int x=0,f=1;char ch=getchar();
27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
29     return x*f;
30 }
31 int n,m,tot,a[maxn],b[maxn],f[maxn];
32 struct seg{int l,r,mx;}t[4*maxn];
33 void build(int k,int l,int r)
34 {
35     t[k].l=l;t[k].r=r;int mid=(l+r)>>1;t[k].mx=-inf;
36     if(l==r)return;
37     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
38 }
39 void change(int k,int x,int y)
40 {
41     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
42     if(l==r){t[k].mx=max(t[k].mx,y);return;}
43     if(x<=mid)change(k<<1,x,y);else change(k<<1|1,x,y);
44     t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
45 }
46 int query(int k,int x,int y)
47 {
48     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
49     if(l==x&&r==y)return t[k].mx;
50     if(y<=mid)return query(k<<1,x,y);
51     else if(x>mid)return query(k<<1|1,x,y);
52     else return max(query(k<<1,x,mid),query(k<<1|1,mid+1,y));
53 }
54 int main()
55 {
56     freopen("input.txt","r",stdin);
57     freopen("output.txt","w",stdout);
58     n=read();m=read();
59     for1(i,n)a[i]=read();
60     for1(i,n)b[i]=b[i-1]+read();
61     build(1,0,n);
62     f[tot=0]=m;change(1,0,m);
63     //for1(i,4*n)cout<<i<<' '<<t[i].l<<' '<<t[i].r<<' '<<t[i].mx<<endl;
64     for1(i,n)
65     {
66       int x=lower_bound(f,f+tot+1,a[i])-f,y;
67       if(f[x]<a[i])continue;else y=query(1,x,tot);
68       //for0(j,tot)cout<<j<<' '<<f[j]<<endl;
69       //cout<<i<<' '<<x<<' '<<y<<endl;
70       if(i==n){printf("%d\n",y+b[i]-a[i]);return 0;}
71       if(y+b[i]-a[i]>f[tot])
72        {
73            //cout<<tot<<' '<<f[tot]<<endl;
74         f[++tot]=y+b[i]-a[i];
75         change(1,tot,f[tot]-b[i]);
76        }
77     }
78     return 0;
79 }
View Code

相关文章: