zoukankan      html  css  js  c++  java
  • [USACO13DEC] Optimal Milking

    Description

    n个点排成一排,点有点权,要求支持两种操作:

    1. 修改某个点的点权
    2. 询问取出任意多且不相邻的点的点权和最大值

    Solution

    跟最大子段和一样,可以用分治做,用线段树记录一下左右端点选没选就行了。

    然而并想不到

    Code

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 40005
    typedef long long ll;
    using std::min;
    using std::max;
    using std::swap;
    #define ls cur<<1
    #define rs cur<<1|1
    
    int n,m,val[N];
    int mx[N<<2][4];//0 not not  1 not yes   2 yes not   3 yes yes
    //0->0+2 1+0 0+0
    //1->0+3 0+1 1+1
    //2->3+0 2+0 2+2
    //3->2+1 3+1 2+3
    
    void pushup(int cur){
        mx[cur][0]=max(mx[ls][0]+mx[rs][2],max(mx[ls][1]+mx[rs][0],mx[ls][0]+mx[rs][0]));
        mx[cur][1]=max(mx[ls][0]+mx[rs][3],max(mx[ls][0]+mx[rs][1],mx[ls][1]+mx[rs][1]));
        mx[cur][2]=max(mx[ls][3]+mx[rs][0],max(mx[ls][2]+mx[rs][0],mx[ls][2]+mx[rs][2]));
        mx[cur][3]=max(mx[ls][2]+mx[rs][1],max(mx[ls][3]+mx[rs][1],mx[ls][2]+mx[rs][3]));
    }
    
    inline int getint(){
        int X=0;int w=0;char ch=0;
        while(!isdigit(ch))w|=ch=='-',ch=getchar();
        while( isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    
    void build(int cur,int l,int r){
        if(l==r){
            mx[cur][0]=mx[cur][1]=mx[cur][2]=0;
            mx[cur][3]=val[l];
            return;
        }
        int mid=l+r>>1;
        build(cur<<1,l,mid);build(cur<<1|1,mid+1,r);
        pushup(cur);
    }
    
    void modify(int cur,int l,int r,int ql,int c){
        if(l==r){
            mx[cur][3]=c;
            return;
        }
        int mid=l+r>>1;
        if(ql<=mid) modify(cur<<1,l,mid,ql,c);
        else modify(cur<<1|1,mid+1,r,ql,c);
        pushup(cur);
    }
    
    signed main(){
        // freopen("in.txt","r",stdin);
        n=getint();m=getint();
        for(int i=1;i<=n;i++)
            val[i]=getint();
        build(1,1,n);
        ll ans=0;
        while(m--){
            int x=getint(),y=getint();
            modify(1,1,n,x,y);
            ans+=(ll)max(mx[1][0],max(mx[1][2],max(mx[1][3],mx[1][1])));
        } printf("%lld
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    Subsequence
    【模板】AC自动机(加强版)
    1563: hzwer的跳跳棋(hop)
    P2469 [SDOI2010]星际竞速
    P2746 [USACO5.3]校园网Network of Schools
    Blocks
    Training little cats
    Period
    UVA-3942 Remember the Word
    初学线段树(poj3264+poj2777)
  • 原文地址:https://www.cnblogs.com/YoungNeal/p/9571037.html
Copyright © 2011-2022 走看看