码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3638缓存

时间:2016-06-29 18:42:15      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:

技术分享
#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缓存

标签:

原文地址:http://www.cnblogs.com/DaD3zZ-Beyonder/p/5627738.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!