BZOJ3638缓存

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3638缓存相关的知识,希望对你有一定的参考价值。

技术分享
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
inline int read()
{
    int 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;
}
#define maxn 101000
int n,m,a[maxn],ans;
struct DataNode
{
    int lx,rx,mx,sum,pl,pr,p1,p2;
    void add(int pos,int x) {p1=p2=pl=pr=pos,mx=sum=lx=rx=x;}
};
struct SegmentTreeNode
{
    int l,r,tag;
    DataNode maxx,minn;
    void add(int pos,int x) {maxx.add(pos,x); minn.add(pos,-x);}
}tree[maxn<<2];
inline DataNode Merge(DataNode ls,DataNode rs)
{
    DataNode rt;
    rt.sum=ls.sum+rs.sum;
    rt.lx=ls.sum+rs.lx>ls.lx? ls.sum+rs.lx : ls.lx;
    rt.pl=ls.sum+rs.lx>ls.lx? rs.pl : ls.pl;
    rt.rx=rs.sum+ls.rx>rs.rx? rs.sum+ls.rx : rs.rx;
    rt.pr=rs.sum+ls.rx>rs.rx? ls.pr : rs.pr;
    
    rt.mx=ls.rx+rs.lx; rt.p1=ls.pr; rt.p2=rs.pl;
    if (rt.mx<ls.mx) rt.mx=ls.mx,rt.p1=ls.p1,rt.p2=ls.p2;
    if (rt.mx<rs.mx) rt.mx=rs.mx,rt.p1=rs.p1,rt.p2=rs.p2;
    
    return rt;
}
inline void Update(int now)
{
    tree[now].minn=Merge(tree[now<<1].minn,tree[now<<1|1].minn);
    tree[now].maxx=Merge(tree[now<<1].maxx,tree[now<<1|1].maxx);
}
inline void Pushdown(int now)
{
    if (!tree[now].tag || tree[now].l==tree[now].r) return;
    tree[now].tag=0;
    swap(tree[now<<1].maxx,tree[now<<1].minn);
    swap(tree[now<<1|1].minn,tree[now<<1|1].maxx);
    tree[now<<1].tag^=1; tree[now<<1|1].tag^=1;        
}
inline void BuildTree(int now,int l,int r)
{
    tree[now].l=l; tree[now].r=r; tree[now].tag=0;
    if (l==r) {tree[now].add(l,a[l]); return;}
    int mid=(l+r)>>1;
    BuildTree(now<<1,l,mid); BuildTree(now<<1|1,mid+1,r);
    Update(now);
}
inline void Change(int now,int pos,int x)
{
    Pushdown(now);
    if (tree[now].l==tree[now].r) {tree[now].add(tree[now].l,x); return;}
    int mid=(tree[now].l+tree[now].r)>>1;
    if (pos<=mid) Change(now<<1,pos,x); else Change(now<<1|1,pos,x);
    Update(now);
}
inline DataNode Query(int now,int L,int R)
{
    Pushdown(now);
    if (L<=tree[now].l && R>=tree[now].r) return tree[now].maxx;
    int mid=(tree[now].l+tree[now].r)>>1;
    DataNode re; re.add(0,0);
    if (L<=mid) re=Merge(re,Query(now<<1,L,R));
    if (R>mid) re=Merge(re,Query(now<<1|1,L,R));
    return re;
}
inline void Reverse(int now,int L,int R)
{
    Pushdown(now);
    if (L<=tree[now].l && R>=tree[now].r) 
        {swap(tree[now].maxx,tree[now].minn); tree[now].tag^=1; return;}
    int mid=(tree[now].r+tree[now].l)>>1;
    if (L<=mid) Reverse(now<<1,L,R);
    if (R>mid) Reverse(now<<1|1,L,R);
    Update(now);
}
struct StackNode
{
    int l,r;
    void Push(int L,int R) {l=L,r=R;}
}stack[21];
int top;
inline void SolveAsk(int L,int R,int K)
{
    ans=0; top=0;
    while (K--)
        {
            DataNode tmp=Query(1,L,R);
            if (tmp.mx>0) ans+=tmp.mx; else break;
            Reverse(1,tmp.p1,tmp.p2);
            stack[++top].Push(tmp.p1,tmp.p2);
        }
    for (int i=1; i<=top; i++)
        Reverse(1,stack[i].l,stack[i].r);
    printf("%d\\n",ans);        
}
inline void SolveChange(int pos,int x) {Change(1,pos,x);}
int main()
{
    n=read();
    for (int i=1; i<=n; i++) a[i]=read();
    BuildTree(1,1,n);
    m=read();
    while (m--)
        {
            int opt=read(),L,R,K,x,d;
            switch (opt)
                {
                    case 1 : L=read(),R=read(),K=read(); SolveAsk(L,R,K); break;
                    case 2 : x=read(),d=read(); SolveChange(x,d); break;
                }
        }
    return 0;
}
View Code

目前状态  50ms RE

以上是关于BZOJ3638缓存的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3638 Cf172 k-Maximum Subsequence Sum

BZOJ3638Cf172 k-Maximum Subsequence Sum 线段树区间合并(模拟费用流)

BZOJ-3638&3272&3267&3502k-Maximum Subsequence Sum 费用流构图 + 线段树手动增广

bzoj3638Cf172 k-Maximum Subsequence Sum 模拟费用流+线段树区间合并

BZOJ.3638.CF172 k-Maximum Subsequence Sum(模拟费用流 线段树)

Android获取各个应用程序的缓存文件代码小片段(使用AIDL)