1367: [Baltic2004]sequence
Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 932 Solved: 348
[Submit][Status][Discuss]
Description
![](http://www.lydsy.com/JudgeOnline/images/1367_1.jpg)
Input
![](http://www.lydsy.com/JudgeOnline/images/1367_2.jpg)
Output
一个整数R
Sample Input
7
9
4
8
20
14
15
18
9
4
8
20
14
15
18
Sample Output
13
HINT
所求的Z序列为6,7,8,13,14,15,18.
R=13
Source
Solution
论文中的例题,非常吼啊....思想巧妙
Code
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; int read() { int x=0,f=1; char ch=getchar(); while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } #define maxn 1000100 long long ans; int n,data[maxn],root[maxn],L[maxn],R[maxn],cnt[maxn],tot; struct LeftTreeNode { int sz,son[maxn][2],d[maxn],size[maxn],a[maxn]; // LeftTreeNode () // { // sz=0;memset(son,0,sizeof(son));memset(size,0,sizeof(size)); // memset(cnt,0,sizeof(cnt));memset(a,0,sizeof(a));memset(d,0,sizeof(d)); // } int Merge(int x,int y) { if (!x) return y; if (!y) return x; if (a[x]<a[y]) swap(x,y); son[x][1]=Merge(son[x][1],y); size[x]=size[son[x][0]]+size[son[x][1]]+1; if (d[son[x][1]]>d[son[x][0]]) swap(son[x][0],son[x][1]); d[x]=d[son[x][1]]+1; return x; } int Push(int x) { a[++sz]=x; size[sz]=1; son[sz][0]=son[sz][1]=d[sz]=0; return sz; } int Pop(int x) {return Merge(son[x][0],son[x][1]);} int Top(int x) {return a[x];} int Size(int x) {return size[x];} }LTHeap; int main() { n=read(); for (int i=1; i<=n; i++) data[i]=read()-i; for (int i=1; i<=n; i++) { tot++; root[tot]=LTHeap.Push(data[i]); cnt[tot]=1; L[tot]=R[tot]=i; while (tot>1 && LTHeap.Top(root[tot])<LTHeap.Top(root[tot-1])) { tot--; root[tot]=LTHeap.Merge(root[tot],root[tot+1]); cnt[tot]+=cnt[tot+1]; R[tot]=R[tot+1]; while (LTHeap.Size(root[tot])*2>cnt[tot]+1) root[tot]=LTHeap.Pop(root[tot]); } } for (int i=1; i<=tot; i++) for (int j=L[i],top=LTHeap.Top(root[i]); j<=R[i]; j++) ans+=abs(data[j]-top); printf("%lld\n",ans); return 0; }
被YveH发现了...