「题解」:[splay]营业额统计
没错这就是让我深陷splay之中的罪魁祸首,昨天打了一下午结果发现是玄学错误的那个
人生第一棵splay平衡树
题目大意:求一段序列,小于当前元素的最大值和大于当前元素的最小值。从该元素前面的元素找。(颓的别人的概括)
题解:
几乎是splay裸题了。
只需要注意一下本身,加一个特判:插入前cnt不为零或者是插入后cnt大于1。(不知道为啥,前者跑了900毫,后者只需要100毫……)
然后我就顺手写了一个小函数判定(其实就是找到该数字对应的下标)
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define inf 0x3f3f3f3f using namespace std; struct ing{ int fa,ch[2],data,cnt,size; }t[200003]; int tot=0,n,dy,root=0,ans=0; inline void rotate( int x) { int y=t[x].fa; int z=t[y].fa; int k=t[y].ch[1]==x; t[x].fa=z; t[z].ch[t[z].ch[1]==y]=x; t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].fa=y; t[x].ch[k^1]=y; t[y].fa=x; } inline void splay( int x, int goal) { while (t[x].fa!=goal) { int y=t[x].fa; int z=t[y].fa; if (z!=goal) (x==t[y].ch[0])^(y==t[z].ch[0])?rotate(x):rotate(y); rotate(x); } if (goal==0)root=x; } inline void find( int x) { int u=root; if (!u) return ; while (t[u].ch[x>t[u].data]&&t[u].data!=x) u=t[u].ch[x>t[u].data]; splay(u,0); } inline void insert( int x) { int u=root,ff=0; while (u&&t[u].data!=x) { ff=u; u=t[u].ch[x>t[u].data]; } if (u) t[u].cnt++; else { u=++tot; if (ff) t[ff].ch[x>t[ff].data]=u; t[u].ch[0]=t[u].ch[1]=0; t[tot].fa=ff; t[tot].data=x; t[tot].cnt=1; t[tot].size=1; } splay(u,0); } inline int nxt( int x, int f) { find(x); int u=root; if (t[u].data>x&&f) return u; if (t[u].data<x&&!f) return u; u=t[u].ch[f]; while (t[u].ch[f^1])u=t[u].ch[f^1]; return u; } inline int dre( int x) { int u=root; while (u&&t[u].data!=x) u=t[u].ch[x>t[u].data]; return u; } int main() { // freopen("data.in","r",stdin); scanf ( "%d" ,&n); scanf ( "%d" ,&dy); insert(inf),insert(-inf); ans+=dy; insert(dy); for ( register int i=2;i<=n;++i) { if ( scanf ( "%d" ,&dy)==-1)dy=0; insert(dy); if (t[dre(dy)].cnt>1) continue ; // cout<<t[nxt(dy,0)].data<<" "<<t[nxt(dy,1)].data<<endl; ans+=min( abs (t[nxt(dy,0)].data-dy), abs (dy-t[nxt(dy,1)].data)); } printf ( "%d\n" ,ans); return 0; } |
P.S.学习splay推荐https://blog.csdn.net/qq_30974369/article/details/77587168,大佬讲的好清楚(就是留坑没有补,少rank操作)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步