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; }
目前状态 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 模拟费用流+线段树区间合并