P1714 切蛋糕-(线段树+倍增+单调队列)

总结

这个题有三种方法写,线段树跟倍增算法其实都差不多,这个题如果用线段树写,就麻烦了,毕竟是离线状态求值,所以单调队列跟倍增更好吧,线段树的代码确实不少,码的话,挺难受的。

解析

pre[i]表示以i结尾的前缀和
p[i]表示以i结尾的子区间的最大和区间和
p[i]=max(pre[i]-pre[j]) max(0,i-k) <= j <= i-1
变形一下:p[i]=pre[i]-min(pre[j]);
这里不就是求得区间最值的问题,离线状态,一次查询,单调队列刚好满足。

题目链接

倍增写法

/*
                ____________    ______________       __
               / _________  /\ /_____   _____/\     / /\
              / /\       / /  \\    /  /\    \ \   / /  \
             / /  \_____/ /   / \__/  /  \____\/  / /   /
            / /   /    / /   /    /  /   /       / /   /
           / /   /    / /   /    /  /   /       / /   /
          / /   /    / /   /    /  /   /       / /   /
         / /___/____/ /   /    /  /   /       / /___/________
        /____________/   /    /__/   /       /______________/\
        \            \  /     \  \  /        \              \ \
         \____________\/       \__\/          \______________\/
           ___       ___               ___    __________
          /  /\     /  /\             /  /\  /_______  /\
         /  /__\___/  /  \           /  /  \ \      /  /  \
        /____    ____/   /          /  /   /  \____/  /   /
        \   /   /\   \  /          /  /   /       /  /   /
         \_/   /  \___\/ ___      /  /   /       /  /   /
          /   /   /     /  /\    /  /   /       /  /   /
         /   /   /     /  /__\__/  /   /       /  /___/____
        /___/   /     /___________/   /       /___________/\
        \   \  /      \           \  /        \           \ \
         \___\/        \___________\/          \___________\/

          A CODE OF CBOY

*/
#include<bits/stdc++.h>
//typedef long long ll;
//#define ull       unsigned long long
//#define int       long long
#define F           first
#define S           second
#define endl        "\n"//<<flush
#define eps         1e-6
#define lowbit(x)   (x&(-x))
#define PI          acos(-1.0)
#define inf         0x3f3f3f3f
#define MAXN        0x7fffffff
#define INF         0x3f3f3f3f3f3f3f3f
#define pa          pair<int,int>
#define ferma(a,b)  pow(a,b-2)
#define pb          push_back
#define all(x)      x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS         ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
void file()
{
#ifdef ONLINE_JUDGE
#else
    freopen("cin.txt","r",stdin);
    //  freopen("cout.txt","w",stdout);
#endif
}
const int N=5e5+5;
int a[N],pre[N];
struct RMQ
{
    vector<vector<int> >ST;
    RMQ(int n=0)
    {
        ST.resize(n+1,vector<int>(21,inf));
        for(int i=1;i<=n;i++)
            ST[i][0]=pre[i];
        for(int i=1;(1<<i)<=n;i++)
            for(int j=1;j+(1<<i)-1<=n;j++)
                ST[j][i]=min(ST[j][i-1],ST[j+(1<<i-1)][i-1]);
    }
    int query(int l,int r)
    {
        int k=log2(r-l+1);
        return min(ST[l][k],ST[r-(1<<k)+1][k]);
    }
};
signed main()
{
    IOS;
    //file();
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i],pre[i]=pre[i-1]+a[i];
    RMQ st(n);
    int ans=-inf;
    for(int i=1;i<=n;i++)
    {
        int l=max(0,i-m),r=i-1;
        ans=max(ans,pre[i]-st.query(l,r));
    }
    cout<<ans<<endl;
    return 0;
}

线段树写法

/*
                ____________    ______________       __
               / _________  /\ /_____   _____/\     / /\
              / /\       / /  \\    /  /\    \ \   / /  \
             / /  \_____/ /   / \__/  /  \____\/  / /   /
            / /   /    / /   /    /  /   /       / /   /
           / /   /    / /   /    /  /   /       / /   /
          / /   /    / /   /    /  /   /       / /   /
         / /___/____/ /   /    /  /   /       / /___/________
        /____________/   /    /__/   /       /______________/\
        \            \  /     \  \  /        \              \ \
         \____________\/       \__\/          \______________\/
           ___       ___               ___    __________
          /  /\     /  /\             /  /\  /_______  /\
         /  /__\___/  /  \           /  /  \ \      /  /  \
        /____    ____/   /          /  /   /  \____/  /   /
        \   /   /\   \  /          /  /   /       /  /   /
         \_/   /  \___\/ ___      /  /   /       /  /   /
          /   /   /     /  /\    /  /   /       /  /   /
         /   /   /     /  /__\__/  /   /       /  /___/____
        /___/   /     /___________/   /       /___________/\
        \   \  /      \           \  /        \           \ \
         \___\/        \___________\/          \___________\/

          A CODE OF CBOY

*/
#include<bits/stdc++.h>
//typedef long long ll;
//#define ull       unsigned long long
//#define int       long long
#define F           first
#define S           second
#define endl        "\n"//<<flush
#define eps         1e-6
#define lowbit(x)   (x&(-x))
#define PI          acos(-1.0)
#define inf         0x3f3f3f3f
#define MAXN        0x7fffffff
#define INF         0x3f3f3f3f3f3f3f3f
#define pa          pair<int,int>
#define ferma(a,b)  pow(a,b-2)
#define pb          push_back
#define all(x)      x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS         ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
void file()
{
#ifdef ONLINE_JUDGE
#else
    freopen("cin.txt","r",stdin);
    //  freopen("cout.txt","w",stdout);
#endif
}
const int N=5e5+5;
int a[N],pre[N];
///注意1:add(0,0,n,x,v)
///注意2:sum(0,0,n,x,y)区间和[x,y]
///注意3:记得空间初始化为n就可以了,内部自动开辟4n空间
struct SegmentTree
{
    vector<int>vec;
    SegmentTree(int n=0)
    {
        vec.resize(n<<2,inf);
    }
    void up(int p)
    {
        vec[p]=min(vec[p*2+1],vec[p*2+2]);
    }
    void add(int p,int l,int r,int x,int v)
    {
        if(l==r)
        {
            vec[p]=v;
            return ;
        }
        int mid=(l+r)>>1;
        if(x<=mid)
            add(p*2+1,l,mid,x,v);
        else
            add(p*2+2,mid+1,r,x,v);
        up(p);
    }
    int sum(int p,int l,int r,int x,int y)
    {
        if(x<=l&&r<=y)
            return vec[p];
        int mid=(l+r)>>1,res=inf;
        if(x<=mid)
            res=min(res,sum(p*2+1,l,mid,x,y));
        if(mid<y)
            res=min(res,sum(p*2+2,mid+1,r,x,y));
        return res;
    }
};

signed main()
{
    IOS;
    //file();
    int n,m;
    cin>>n>>m;
    SegmentTree st(n);
    st.add(0,0,n,0,0);
    for(int i=1;i<=n;i++)
        cin>>a[i],pre[i]=pre[i-1]+a[i],st.add(0,0,n,i,pre[i]);
    int ans=-inf;
    for(int i=1;i<=n;i++)
    {
        int l=max(0,i-m),r=i-1;
        ans=max(ans,pre[i]-st.sum(0,0,n,l,r));
    }
    cout<<ans<<endl;
    return 0;
}

单调队列

/*
                ____________    ______________       __
               / _________  /\ /_____   _____/\     / /\
              / /\       / /  \\    /  /\    \ \   / /  \
             / /  \_____/ /   / \__/  /  \____\/  / /   /
            / /   /    / /   /    /  /   /       / /   /
           / /   /    / /   /    /  /   /       / /   /
          / /   /    / /   /    /  /   /       / /   /
         / /___/____/ /   /    /  /   /       / /___/________
        /____________/   /    /__/   /       /______________/\
        \            \  /     \  \  /        \              \ \
         \____________\/       \__\/          \______________\/
           ___       ___               ___    __________
          /  /\     /  /\             /  /\  /_______  /\
         /  /__\___/  /  \           /  /  \ \      /  /  \
        /____    ____/   /          /  /   /  \____/  /   /
        \   /   /\   \  /          /  /   /       /  /   /
         \_/   /  \___\/ ___      /  /   /       /  /   /
          /   /   /     /  /\    /  /   /       /  /   /
         /   /   /     /  /__\__/  /   /       /  /___/____
        /___/   /     /___________/   /       /___________/\
        \   \  /      \           \  /        \           \ \
         \___\/        \___________\/          \___________\/

          A CODE OF CBOY

*/
#include<bits/stdc++.h>
//typedef long long ll;
//#define ull       unsigned long long
//#define int       long long
#define F           first
#define S           second
#define endl        "\n"//<<flush
#define eps         1e-6
#define lowbit(x)   (x&(-x))
#define PI          acos(-1.0)
#define inf         0x3f3f3f3f
#define MAXN        0x7fffffff
#define INF         0x3f3f3f3f3f3f3f3f
#define pa          pair<int,int>
#define ferma(a,b)  pow(a,b-2)
#define pb          push_back
#define all(x)      x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS         ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
void file()
{
#ifdef ONLINE_JUDGE
#else
    freopen("cin.txt","r",stdin);
    //  freopen("cout.txt","w",stdout);
#endif
}
const int N=5e5+5;
int pre[N];
signed main()
{
    IOS;
    //file();
    int n,m;
    cin>>n>>m;
    deque<int>de;
    int ans=-inf;
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x,pre[i]=pre[i-1]+x;
        while(!de.empty()&&de.front()<i-m)de.pop_front();
        int pos=(de.empty()?0:de.front());
        ans=max(ans,pre[i]-pre[pos]);
        while(!de.empty()&&pre[de.back()]>=pre[i])de.pop_back();
        de.push_back(i);
    }
    cout<<ans<<endl;
    return 0;
}

发布了149 篇原创文章 · 获赞 5 · 访问量 6898

猜你喜欢

转载自blog.csdn.net/weixin_44224825/article/details/104562566