uoj 279: 数据分块鸡 动态规划+可持久化线段树

来源:互联网 发布:淘宝曼哈顿直通车真假 编辑:程序博客网 时间:2024/05/16 13:48

        一开始看到这道题目的时候以为是dp+线段树修改什么的来维护。

       但是n=50000好奇怪啊。

       看了题解才知道原来是决策单调性+暴力可持久化线段树求某一个区间的花费。

       刚好没有怎么写过dp决策单调性的优化,就写一发吧。

AC代码如下:

#include<bits/stdc++.h>#define ll long long#define N 100005#define M 2000005using namespace std;int n,m,trtot,fst[N],pnt[N],nxt[N],rt[N],ls[M],rs[M],q[N],lf[N]; ll f[N];struct node{ int x; ll y,z; }val[M];node operator +(node u,node v){ return (node){u.x+v.x,u.y+v.y,u.z+v.z}; }node operator -(node u,node v){ return (node){u.x-v.x,u.y-v.y,u.z-v.z}; }void ins(int l,int r,int x,int &y,int u,node v){y=++trtot; val[y]=val[x]+v;if (l==r) return;int mid=l+r>>1;if (u<=mid){ rs[y]=rs[x]; ins(l,mid,ls[x],ls[y],u,v); }else{ ls[y]=ls[x]; ins(mid+1,r,rs[x],rs[y],u,v); }}node getsum(int x,int y,int k){int l=1,r=n,mid; node ans=(node){0,0,0};if (!k || x>y) return ans;x=rt[x-1]; y=rt[y];while (l<r){mid=l+r>>1;if (k>mid){ans=ans+val[ls[y]]-val[ls[x]];l=mid+1; x=rs[x]; y=rs[y];} else{r=mid; x=ls[x]; y=ls[y];}}return ans+val[y]-val[x];}ll calc(int l,int r){ll ans=getsum(r,n,l).x;node u=val[rt[r]]-getsum(1,r,l-1);ans+=(ll)u.x*(r-l)+u.y-u.z;int mid=l+r>>1;u=getsum(l,mid,l-1);ans+=u.z-(ll)u.x*l;u=getsum(mid+1,r,l-1);ans+=(ll)u.x*r-u.z;u=getsum(r+1,n,mid);node v=getsum(r+1,n,r)-u; u=u-getsum(r+1,n,l);ans+=(ll)v.x*r-v.y+u.y-(ll)u.x*l;return f[l]+ans;}int main(){scanf("%d%d",&n,&m);int i,x,y;for (i=1; i<=m; i++){scanf("%d%d",&x,&y);pnt[i]=x; nxt[i]=fst[y]; fst[y]=i;}for (y=1; y<=n; y++){rt[y]=rt[y-1];for (i=fst[y]; i; i=nxt[i]){x=pnt[i];ins(1,n,rt[y],rt[y],x,(node){1,x,y});}}f[1]=0; q[1]=1; lf[1]=2;int head=1,tail=1;for (i=2; i<=n; i++){if (head<tail && lf[head+1]<=i) head++;f[i]=calc(q[head],i);if (i<n){for (; i<lf[tail] && calc(q[tail],lf[tail])>=calc(i,lf[tail]); tail--);int l=max(i,lf[tail])+1,r=n,mid;while (l<r){mid=l+r>>1;if (calc(q[tail],mid)<calc(i,mid)) l=mid+1; else r=mid;}if (l<=n && calc(q[tail],l)>=calc(i,l)){ q[++tail]=i; lf[tail]=l; }}}printf("%lld\n",f[n]);return 0;}


by lych

2017.2.2

1 0
原创粉丝点击