最近各种瞎写数论题,感觉需要回顾一下数据结构
写一发splay冷静一下(手速过慢,以后要多练练)
用splay是最直接的方法,但我感觉离散一波应该可以做出来(没仔细想过)
现在没有很追求代码优美,感觉得先打的对打的快O(∩_∩)O
1 #include <bits/stdc++.h> 2 #define INF 1000000000 3 using namespace std; 4 int root,N,n,x; 5 int fa[100005],c[100005][2],a[100005]; 6 void rot(int x) 7 { 8 int fat=fa[x],k=c[fat][1]==x; 9 c[fat][k]=c[x][!k];fa[c[x][!k]]=fat; 10 fa[x]=fa[fat];c[fa[fat]][c[fa[fat]][1]==fat]=x; 11 fa[fat]=x;c[x][!k]=fat; 12 } 13 void splay(int x,int g) 14 { 15 for(int y;(y=fa[x])!=g;rot(x)) 16 if(fa[y]!=g) 17 if((c[y][1]==x)==(c[fa[y]][1]==y)) rot(y);else rot(x); 18 if(g==0) root=x; 19 } 20 int lower(int p) 21 { 22 if(!root) return 0; 23 int ans=INF; 24 for(int i=root;i;(p>=a[i])?i=c[i][1]:i=c[i][0]) 25 if(a[i]>=p) 26 ans=min(ans,a[i]); 27 return ans-p; 28 } 29 int upper(int p) 30 { 31 if(!root) return 0; 32 int ans=-INF; 33 for(int i=root;i;(p>=a[i])?i=c[i][1]:i=c[i][0]) 34 if(a[i]<=p) 35 ans=max(ans,a[i]); 36 return p-ans; 37 } 38 void add(int x) 39 { 40 a[++N]=x;c[N][0]=c[N][1]=0; 41 if(!root) 42 { 43 root=N; 44 return; 45 } 46 for(int i=root;1;) 47 if(x<=a[i]) 48 if(!c[i][0]) 49 { 50 c[i][0]=N,fa[N]=i; 51 splay(N,0); 52 break; 53 } 54 else i=c[i][0]; 55 else 56 if(!c[i][1]) 57 { 58 c[i][1]=N,fa[N]=i; 59 splay(N,0); 60 break; 61 } 62 else i=c[i][1]; 63 } 64 int main() 65 { 66 scanf("%d",&n);int ans=0; 67 for(int i=1;i<=n;i++) 68 { 69 scanf("%d",&x); 70 if(i==1) ans+=x; 71 else 72 ans+=min(upper(x),lower(x)); 73 add(x); 74 } 75 printf("%d ",ans); 76 return 0; 77 }