zoukankan      html  css  js  c++  java
  • Codeforces Gym 100513F F. Ilya Muromets 线段树

    F. Ilya Muromets

    Time Limit: 20 Sec

    Memory Limit: 256 MB

    题目连接

    http://codeforces.com/gym/100513/problem/F

    Description

    I

    Ilya Muromets is a legendary bogatyr. Right now he is struggling against Zmej Gorynych, a dragon with n heads numbered from 1 to nfrom left to right.

    Making one sweep of sword Ilya Muromets can cut at most k contiguous heads of Zmej Gorynych. Thereafter heads collapse getting rid of empty space between heads. So in a moment before the second sweep all the heads form a contiguous sequence again.

    As we all know, dragons can breathe fire. And so does Zmej Gorynych. Each his head has a firepower. The firepower of the i-th head isfi.

    Ilya Muromets has time for at most two sword sweeps. The bogatyr wants to reduce dragon's firepower as much as possible. What is the maximum total firepower of heads which Ilya can cut with at most two sword sweeps?

    Input

    The first line contains a pair of integer numbers n and k (1 ≤ n, k ≤ 2·105) — the number of Gorynych's heads and the maximum number of heads Ilya can cut with a single sword sweep. The second line contains the sequence of integer numbers f1, f2, ..., fn(1 ≤ fi ≤ 2000), where fi is the firepower of the i-th head.

    Output

    Print the required maximum total head firepower that Ilya can cut.

    Sample Input

    8 2
    1 3 3 1 2 3 11 1

    Sample Output

    20

    HINT

    题意

    一个人可以砍两刀,每刀可以消去连续的K个数,然后问你两刀最多能砍下数的和是多少

    题解

    线段树,枚举这一块,然后除了这一块的其他块都是可以选择的

    查询区间最大值就好了

    代码

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define test freopen("test.txt","r",stdin)
    const int maxn=2025001;
    #define mod 1000000007
    #define eps 1e-9
    const int inf=0x3f3f3f3f;
    const ll infll = 0x3f3f3f3f3f3f3f3fLL;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //**************************************************************************************
    struct node
    {
        int l,r,ma,mi;
    }a[maxn];
    int d[maxn];
    void build(int x,int l,int r)
    {
        a[x].l=l,a[x].r=r;
        a[x].ma=-inf,a[x].mi=inf;
        if(l==r)
        {
            a[x].ma=d[l];
            a[x].mi=d[l];
            return;
        }
        else
        {
            int mid=(l+r)>>1;
            build(x<<1,l,mid);
            build(x<<1|1,mid+1,r);
            a[x].ma=max(a[x<<1].ma,a[x<<1|1].ma);
            a[x].mi=min(a[x<<1].mi,a[x<<1|1].mi);
        }
    }
    int query1(int x,int st,int ed)
    {
        int l=a[x].l,r=a[x].r;
        if(st<=l&&r<=ed)
            return a[x].mi;
        else
        {
            int mid=(l+r)>>1;
            int mi1=inf,mi2=inf;
            if(st<=mid)
                mi1=query1(x<<1,st,ed);
            if(ed>mid)
                mi2=query1(x<<1|1,st,ed);
            return min(mi1,mi2);
        }
    }
    
    int query2(int x,int st,int ed)
    {
        int l=a[x].l,r=a[x].r;
        if(st<=l&&r<=ed)
            return a[x].ma;
        else
        {
            int mid=(l+r)>>1;
            int mi1=-inf,mi2=-inf;
            if(st<=mid)
                mi1=query2(x<<1,st,ed);
            if(ed>mid)
                mi2=query2(x<<1|1,st,ed);
            return max(mi1,mi2);
        }
    }
    int aa[maxn];
    int dp[maxn];
    int sum=0;
    int main()
    {
        int n=read(),k=read();
        for(int i=1;i<=n;i++)
            aa[i]=read();
        for(int i=1;i<=n;i++)
            sum=sum+aa[i];
        for(int i=1;i<=k;i++)
            dp[i]+=aa[i]+dp[i-1];
        for(int i=k+1;i<=n;i++)
            dp[i]=dp[i-1]+aa[i]-aa[i-k];
        if(2*k>=n)
        {
            cout<<sum<<endl;
            return 0;
        }
        int ans=0;
        for(int i=1;i<=n-k+1;i++)
            d[i]=dp[k-1+i];
        build(1,1,n-k+1);
        for(int i=1;i<=n-k+1;i++)
        {
            if(i>k)
            {
                ans=max(ans,d[i]+query2(1,1,i-k));
            }
            else
                ans=max(ans,d[i]);
        }
        cout<<ans<<endl;
    }
  • 相关阅读:
    0015 Java学习笔记-集合-TreeMap集合
    0014 Java学习笔记-集合-HashMap集合
    0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类
    0012 win7x64安装CentOS7
    0011《SQL必知必会》笔记07 数据的插入、更新和删除
    0010《SQL必知必会》笔记06-表的修改与删除
    0009《SQL必知必会》笔记05-表的创建与约束
    0008《SQL必知必会》笔记04-子查询、联接与组合查询
    0007《SQL必知必会》笔记03-汇总与分组数据
    0006 《SQL必知必会》笔记02-计算字段与函数
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4671303.html
Copyright © 2011-2022 走看看