生活随笔
收集整理的這篇文章主要介紹了
bzoj1588营业额统计
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
營業額統計 Tiger最近被公司升任為營業部經理,他上任后接受公司交給的第一項任務便是統計并分析公司成立以來的營業情況。 Tiger拿出了公司的賬本,賬本上記錄了公司成立以來每天的營業額。分析營業情況是一項相當復雜的工作。由于節假日,大減價或者是其他情況的時候,營業額會出現一定的波動,當然一定的波動是能夠接受的,但是在某些時候營業額突變得很高或是很低,這就證明公司此時的經營狀況出現了問題。經濟管理學上定義了一種最小波動值來衡量這種情況: 該天的最小波動值 當最小波動值越大時,就說明營業情況越不穩定。 而分析整個公司的從成立到現在營業情況是否穩定,只需要把每一天的最小波動值加起來就可以了。你的任務就是編寫一個程序幫助Tiger來計算這一個值。 第一天的最小波動值為第一天的營業額。 ? 輸入輸出要求
Input
第一行為正整數 ,表示該公司從成立一直到現在的天數,接下來的n行每行有一個整數(有可能有負數) ,表示第i
天公司的營業額。
天數n<=32767,每天的營業額ai <= 1,000,000。
最后結果T<=2^31
Output
輸出文件僅有一個正整數,即Sigma(每天最小的波動值) 。結果小于2^31 。
Sample Input
6
5
1
2
5
4
6
Sample Output
12
分析:
以權值為下標建一顆線段樹.
每次插一個新值, 并查詢小于它的最大值和大于它的最小值.
這里寫代碼片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long longusing namespace std;
const int N=
40000;
const int INF=
0x33333333;
struct node{
int x,y,mx,mn,v;
};
node tree[
40000<<
2];
int n,num[N];
ll ans=
0;
struct node1{
int bh,v;
};
node1 a[N];
int cmp(
const node1 &a,
const node1 &b)
{
return a.v<b.v;
}
void update(
int bh)
{
int lc=bh<<
1;
int rc=bh<<
1|
1;
if (tree[bh].x!=tree[bh].y){tree[bh].mx=max(tree[lc].mx,tree[rc].mx);tree[bh].mn=min(tree[lc].mn,tree[rc].mn);}
return;
}
void build(
int bh,
int l,
int r)
{tree[bh].x=l;tree[bh].y=r;
if (l==r) {tree[bh].mx=-INF;tree[bh].mn=INF;
return;}
int mid=(l+r)>>
1;build(bh<<
1,l,mid);build(bh<<
1|
1,mid+
1,r);update(bh);
}
void add(
int bh,
int mb,
int v)
{
if (tree[bh].x==mb&&tree[bh].y==mb) {tree[bh].v=v; tree[bh].mx=v;tree[bh].mn=v;
return;}
int mid=(tree[bh].x+tree[bh].y)>>
1;
if (mb<=mid) add(bh<<
1,mb,v);
if (mb>mid) add(bh<<
1|
1,mb,v);update(bh);
}
int ask(
int bh,
int l,
int r,
int lx)
{
if (r<l) {
if (lx==
1)
return -INF;
else return INF;}
if (tree[bh].x>=l&&tree[bh].y<=r){
if (lx==
1)
return tree[bh].mx;
else return tree[bh].mn;}
int mid=(tree[bh].x+tree[bh].y)>>
1;
int ans;
if (lx==
1) ans=-INF;
else ans=INF;
if (l<=mid){
if (lx==
1)ans=max(ans,ask(bh<<
1,l,r,lx));
else ans=min(ans,ask(bh<<
1,l,r,lx));}
if (r>mid) {
if (lx==
1)ans=max(ans,ask(bh<<
1|
1,l,r,lx));
else ans=min(ans,ask(bh<<
1|
1,l,r,lx));}
return ans;
}
int main()
{
scanf(
"%d",&n);
for (
int i=
1;i<=n;i++)
scanf(
"%d",&a[i].v),a[i].bh=i; sort(a+
1,a+
1+n,cmp);build(
1,
1,n);
for (
int i=
1;i<=n;i++) num[a[i].bh]=i; add(
1,num[
1],a[num[
1]].v); ans+=(ll)a[num[
1]].v;
for (
int i=
2;i<=n;i++){add(
1,num[i],a[num[i]].v);
int maxx=ask(
1,
1,num[i]-
1,
1);
int minn=ask(
1,num[i]+
1,n,
2);
int t=min(
abs(a[num[i]].v-minn),
abs(maxx-a[num[i]].v));ans+=(ll)t; }
printf(
"%lld",ans);
return 0;
}
轉載于:https://www.cnblogs.com/wutongtong3117/p/7673520.html
總結
以上是生活随笔為你收集整理的bzoj1588营业额统计的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。