[***]HZOJ 柱状图
生活随笔
收集整理的這篇文章主要介紹了
[***]HZOJ 柱状图
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
神仙題。
作者的正解:
算法二:對于60%的數據:考慮直接枚舉屋頂的位置,總花費與屋頂的高度的關系是一個單峰函數,,我們可以用三分法三分屋頂的高度.?時間復雜度O(n2*logn)。
?
算法三:對于100%的數據: ?我們枚舉屋頂位置再三分高度的做法,復雜度的瓶頸在于花費的計算。假設屋頂在i處,高度為hi,如果j<i,有hj-j=hi-i ; 如果j>i,有hj+j=hi+i。
根據權值排序,建立樹狀數組來解決權值與i的權值的關系,用兩個樹狀數組維護。時間復雜度O(n(logn)(logv),V為屋頂的高度。
?
對于60%的數據大概有兩種做法:
1.如作者題解,說的挺清楚的。
2.考慮對于一個確定的位置作為屋頂,那么屋頂的高度是確定的,證明以后再說。將每個點的高度加上到屋頂的距離,高度為之后序列的中位數,所以就可以模擬退火了。
對于100%的數據:
1.模擬退火(沒臉)。
2.枚舉屋頂,三分高度,然后主要的優化就是在計算花費上。可以用兩個樹狀數組維護。
由于時間比較緊剩下的先咕掉了……
?
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #define int LL 6 #define LL long long 7 #define MAXN 100010 8 #define reg register 9 #define con const 10 using namespace std; 11 struct node 12 { 13 int val,id; 14 friend bool operator < (node a,node b) 15 {return !(a.val^b.val)?a.id<b.id:a.val<b.val;} 16 }al[MAXN],ar[MAXN]; 17 int n,a[MAXN],maxh,rkl[MAXN],rkr[MAXN]; 18 #define lowbit(x) ((x)&(-(x))) 19 struct bit 20 { 21 int C[MAXN],num[MAXN]; 22 void add(reg int x,reg con int y,reg con int z) 23 {while(x<=n){C[x]+=y;num[x]+=z;x+=lowbit(x);}} 24 pair<int,int> ask(reg int x) 25 { 26 int sum=0,nnum=0; 27 while(x) 28 { 29 sum+=C[x]; 30 nnum+=num[x]; 31 x-=lowbit(x); 32 } 33 return make_pair(sum,nnum); 34 } 35 }le,re; 36 __attribute((always_inline))int get(reg con int x,reg con int maxh) 37 { 38 int ans=0; 39 ans+=abs(maxh-a[x]); 40 int pos=upper_bound(al+1,al+n+1,(node){maxh-x,x})-al-1; 41 pair<int,int> tem=le.ask(pos); 42 ans+=tem.second*(maxh-x)-tem.first; 43 pair<int,int> tem2=le.ask(n); 44 ans+=tem2.first-tem.first-(tem2.second-tem.second)*(maxh-x); 45 pos=upper_bound(ar+1,ar+n+1,(node){maxh+x,x})-ar-1; 46 tem=re.ask(pos); 47 ans+=tem.second*(maxh+x)-tem.first; 48 tem2=re.ask(n); 49 ans+=tem2.first-tem.first-(tem2.second-tem.second)*(maxh+x); 50 return ans; 51 } 52 __attribute((always_inline))void read(int &s) 53 { 54 s=0; 55 reg int f=1;reg char a=getchar(); 56 while(a<'0'||a>'9'){if(a=='-')f=-1;a=getchar();} 57 while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();} 58 s*=f; 59 } 60 signed main() 61 { 62 read(n); 63 int ans=0x7ffffffffffff; 64 for(reg int i=1;i<=n;++i) 65 { 66 read(a[i]); 67 al[i].val=a[i]-i,al[i].id=i; 68 ar[i].val=a[i]+i,ar[i].id=i; 69 } 70 sort(al+1,al+n+1); 71 sort(ar+1,ar+n+1); 72 for(reg int i=1;i<=n;++i)rkl[al[i].id]=i,rkr[ar[i].id]=i; 73 for(reg int i=1;i<=n;++i)re.add(rkr[i],a[i]+i,1); 74 for(reg int i=1;i<=n;++i) 75 { 76 re.add(rkr[i],-a[i]-i,-1); 77 int l=max(i,n-i+1),r=1e9,ml,mr; 78 ans=min(ans,get(i,l)); 79 while(r>l+1) 80 { 81 int mid=(l+r)>>1; 82 ml=mid-1,mr=mid; 83 int ans1=get(i,ml), 84 ans2=get(i,mr); 85 if(ans1<ans2)r=mid; 86 else l=mid; 87 ans=min(ans,ans1); 88 ans=min(ans,ans2); 89 if(!(ml^l)&&!(mr^r))break; 90 } 91 le.add(rkl[i],a[i]-i,1); 92 } 93 printf("%lld\n",ans); 94 } View Code?
?
?
?
?
?
轉載于:https://www.cnblogs.com/Al-Ca/p/11318851.html
總結
以上是生活随笔為你收集整理的[***]HZOJ 柱状图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 暑假N天乐【比赛篇】 —— 2019杭电
- 下一篇: Java爬虫https网页内容报错SSL