[HNOI2002]營業額統計 (Splay)
阿新 • • 發佈:2018-05-31
include oot 行為 輸入格式 void 需要 == splay 定義
唉,我太菜了...
好久沒打過數據結構了哈... 把這道題作為splay 的復習題吧,也是個板子.
題目描述
Tiger最近被公司升任為營業部經理,他上任後接受公司交給的第一項任務便是統計並分析公司成立以來的營業情況。
Tiger拿出了公司的賬本,賬本上記錄了公司成立以來每天的營業額。分析營業情況是一項相當復雜的工作。由於節假日,大減價或者是其他情況的時候,營業額會出現一定的波動,當然一定的波動是能夠接受的,但是在某些時候營業額突變得很高或是很低,這就證明公司此時的經營狀況出現了問題。經濟管理學上定義了一種最小波動值來衡量這種情況:
當最小波動值越大時,就說明營業情況越不穩定。
而分析整個公司的從成立到現在營業情況是否穩定,只需要把每一天的最小波動值加起來就可以了。你的任務就是編寫一個程序幫助Tiger來計算這一個值。
第一天的最小波動值為第一天的營業額。
該天的最小波動值=min{|該天以前某一天的營業額-該天營業額|}。
輸入輸出格式
輸入格式:
輸入由文件’turnover.in’讀入。
第一行為正整數n(n<=32767) ,表示該公司從成立一直到現在的天數,接下來的n行每行有一個整數ai(|ai|<=1000000) ,表示第i天公司的營業額,可能存在負數。
輸出格式:
輸入輸出樣例
輸入樣例#1:
6
5
1
2
5
4
6
輸出樣例#1:
12
說明
結果說明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12
Solution
太久沒打過了,就對著題解一頓打和理解,題意就是找前驅和後繼裏面和自己差的比較小的差值.
#include<bits/stdc++.h>
using namespace std;
const int maxn=40008;
struct sj{
int fa;
int lc;
int rc;
int data;
}tree[maxn];
int n,sum,root,flag;
void zig(int x)
{
int y=tree[x].fa;
int z=tree[y].fa;
tree[y].lc=tree[x].rc;
if(tree[x].rc) tree[tree[x].rc].fa=y;
tree[x].fa=z;
if (z)
{
if(tree[z].lc==y)
tree[z].lc=x;
else tree[z].rc=x;
}
tree[x].rc=y;
tree[y].fa=x;
}
void zag(int x)
{
int y=tree[x].fa;
int z=tree[y].fa;
tree[y].rc=tree[x].lc;
if(tree[x].lc) tree[tree[x].lc].fa=y;
tree[x].fa=z;
if(z)
{
if(tree[z].lc==y)
tree[z].lc=x;
else tree[z].rc=x;
}
tree[x].lc=y;
tree[y].fa=x;
}
inline void splay(int x) //將 x 這個點翻到 根的函數.
{
while(tree[x].fa)//直到把x旋到根
{
int y=tree[x].fa;
int z=tree[y].fa;
if(!z) //如果到了根的下一位.
{
if(tree[y].lc==x) zig(x);
else zag(x);
}
else
//到最後面即將翻到根的時候需要分類討論.
//zig-zig,zag-zag,zig-zag,zag-zig;
{
if(tree[y].lc==x&&tree[z].lc==y)
zig(y),zig(x);
//同為兩遍右,即為 zig-zig.
if(tree[y].rc==x&&tree[z].rc==y)
zag(y),zag(x);
//此種為 zag-zag.
if(tree[y].rc==x&&tree[z].lc==y)
zag(x),zig(x);
//zag-zig;
if(tree[y].lc==x&&tree[z].rc==y)
zig(x),zag(x);
//zig-zag;
}
}
root=x;
//最後面更新根.
}
void build(int x,int rt)
//x為要插入的節點,rt為當前的節點.
{
if(tree[x].data==tree[rt].data)
{
splay(rt);
flag=1;
return;
}
if(tree[x].data<tree[rt].data)
{
if(tree[rt].lc==0)
{
tree[rt].lc=x;
tree[x].fa=rt;
}
else build(x,tree[rt].lc);
}
else
{
if(tree[rt].rc==0)
{
tree[rt].rc=x;
tree[x].fa=rt;
}
else build(x,tree[rt].rc);
}
}
int fro(int x)
{
int y=tree[x].lc;
if(!y)return y;
while(tree[y].rc)
y=tree[y].rc;
return y;
}
int beh(int x)
{
int y=tree[x].rc;
if(!y)return y;
while(tree[y].lc)
y=tree[y].lc;
return y;
}
void insert(int x)
{
flag=0;
build(x,root);
if(flag==1)return;
splay(x);
int q=fro(x),h=beh(x),ans=1e9;
if(q) ans=min(ans,abs(tree[x].data-tree[q].data));
if(h) ans=min(ans,abs(tree[x].data-tree[h].data));
sum+=ans;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
cin>>tree[1].data;
root=1;sum+=tree[1].data;
for(int i=2;i<=n;i++)
{
cin>>tree[i].data;
insert(i);
}
cout<<sum<<endl;
return 0;
}
[HNOI2002]營業額統計 (Splay)