【JZOJ 4623】搬运干草捆
生活随笔
收集整理的這篇文章主要介紹了
【JZOJ 4623】搬运干草捆
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Description
Solution
題解說用splay來解,我不會,我用貪心,
顯然的,在使當(dāng)前答案最優(yōu)的同時,也要保證當(dāng)前做到的最后一個干草的高度最高,
把每個修改后高度一樣的干草合成一個塊,設(shè)每個干草原高度為ai,修改后的整塊的高度為bk。
我們先來考慮局部的解:
當(dāng)前做到i,
如果bk=ai,直接合并上去,
如果bk>ai,新開一個塊,
如果bk<ai有x個,a>bk有y個,
一個結(jié)論:在只有兩個點的情況下,把一個點升高和把另一個點減低的代價是一樣的,
同樣的,如果塊中x=y,那么結(jié)論同樣成立,因為我們可以把它們看成一高一低兩兩配對的點對。
當(dāng)x>y時,只能把i點降低,
當(dāng)x=y時,代價與上情況相同,因為代價不變,可以升高整塊的高度,
找到一個高度q=minaj>bk{aj}(用主席樹)為升高的上限高度,因為如果再升高代價就會變,
如果q大于上一個塊的高度bk?1,顯然不合法,只把當(dāng)前區(qū)間升到bk?1,并把這兩個塊合并,
如果不是,就直接上升到q,
最后的答案就是每個塊的代價和,
復(fù)雜度:O(nlog(n))
圖片from YxuanwKeith
Code
#include<iostream> #include<cstdio> #include<cstdlib> #define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std; typedef long long LL; const int N=100500,INF=2070483640; int read(int &n) {char ch=' ';int q=0,w=1;for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());if(ch=='-')w=-1,ch=getchar();for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n; } int n,m; LL ans; int a[N],za0; struct wqwq {int b,x,y,i;LL ans;}za[N]; struct qqww {int l,r,s;}b[N*50]; int root[N],b0; struct wwq {int s,ans;}; void build(int l,int r,int e1,int &e2,int l2) {b[e2=++b0]=b[e1];if(l==r){b[e2].s++;return;}int t=(l+r)/2;if(l2<=t)build(l,t,b[e1].l,b[e2].l,l2);else build(t+1,r,b[e1].r,b[e2].r,l2);b[e2].s=b[b[e2].l].s+b[b[e2].r].s; } wwq find(int l,int r,int e1,int e2,int l1) {wwq ans;ans.s=b[e2].s-b[e1].s;if(b[e2].s-b[e1].s==0)return ans;if(l==r){ans.ans=l;return ans;}int t=(l+r)/2;if(t<l1)return find(t+1,r,b[e1].r,b[e2].r,l1);else {wwq s=find(l,t,b[e1].l,b[e2].l,l1);if(s.s)return s;return find(t+1,r,b[e1].r,b[e2].r,l1);} } int main() {int mx=0;wwq q;read(n);fo(i,1,n)mx=max(mx,read(a[i]));za[0].b=INF;fo(i,1,n){build(1,mx,root[i-1],root[i],a[i]);if(za[za0].b>a[i])za[++za0].x=1,za[za0].y=0,za[za0].b=a[i],za[za0].ans=0,za[za0].i=i;else if(za[za0].b==a[i])za[za0].x++;else{za[za0].y++;za[za0].ans+=a[i]-za[za0].b;while(za[za0].x==za[za0].y){q=find(1,mx,root[za[za0].i-1],root[i],za[za0].b+1);if(q.ans<=za[za0-1].b)za[za0].x+=q.s,za[za0].y-=q.s,za[za0].b=q.ans;if(q.ans>=za[za0-1].b){za[za0-1].x+=za[za0].x;za[za0-1].y+=za[za0].y;za[za0-1].ans+=za[za0].ans;za0--;}}}}ans=0;fo(i,1,za0)ans+=za[i].ans;printf("%lld\n",ans);return 0; }總結(jié)
以上是生活随笔為你收集整理的【JZOJ 4623】搬运干草捆的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 社会工程学攻击案例-网站钓鱼
- 下一篇: 并发设计模式