zoukankan      html  css  js  c++  java
  • [HNOI2002]营业额统计(Splay模板)

    本来一直嫌麻烦只写spaly,结果被模板题卡T了,只能写正版splay,然后发现原来挺好写的,而且快了好多QwQ。image

    思路:每次对ai统计“最小波动值”的时候有两种情况,aj>=ai和aj<ai,取差值最小的一种。就是ai的前驱和后继,可以用splay维护和查找。

    代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 using namespace std;
      5 
      6 struct SplayNode {
      7 	SplayNode *fa, *son[2];
      8 	int weight;
      9 	SplayNode(SplayNode *f = NULL, int w = 0):fa(f), weight(w) {
     10 		son[0] = son[1] = NULL;
     11 	}
     12 }*root = NULL;
     13 
     14 void rotate(SplayNode*);
     15 void Splay(SplayNode*);
     16 SplayNode *insert(int);
     17 SplayNode *findPredecessor(SplayNode*);
     18 SplayNode *findSuccessor(SplayNode*);
     19 
     20 int main() {
     21 	int n, ans = 0;
     22 	scanf("%d", &n);
     23 	for (int i = 0; i < n; i++) {
     24 		int d;
     25 		scanf("%d", &d);
     26 		if (!root) {
     27 			ans = d;
     28 			root = new SplayNode(NULL, d);
     29 		}
     30 		else {
     31 			SplayNode *p = insert(d);
     32 			int min_d = 0x3f3f3f3f;
     33 			SplayNode *l = findPredecessor(p), *r = findSuccessor(p);
     34 			if (l) min_d = p->weight - l->weight;
     35 			if (r) min_d = min(min_d, r->weight - p->weight);
     36 			ans += min_d;
     37 			//printf("%d
    ", min_d);
     38 		}
     39 	}
     40 	printf("%d
    ", ans);
     41 	return 0;
     42 }
     43 
     44 void rotate(SplayNode *rt) {
     45 	int d = (rt->fa->son[0] == rt);
     46 	SplayNode *f = rt->fa, *s = rt->son[d];
     47 	f->son[d ^ 1] = s;
     48 	if (s) s->fa = f;
     49 	rt->son[d] = f;
     50 	if (f->fa) f->fa->son[f->fa->son[1] == f] = rt;
     51 	rt->fa = f->fa;
     52 	f->fa = rt;
     53 }
     54 
     55 void Splay(SplayNode *rt) {
     56 	while(rt->fa) {
     57 		if (!rt->fa->fa) rotate(rt);
     58 		else {
     59 			int d1 = (rt->fa->son[1] == rt), d2 = (rt->fa->fa->son[1] == rt->fa);
     60 			if (d1 == d2) {
     61 				rotate(rt->fa);
     62 				rotate(rt);
     63 			} else {
     64 				rotate(rt);
     65 				rotate(rt);
     66 			}
     67 		}
     68 	}
     69 	root = rt;
     70 }
     71 
     72 SplayNode *insert(int w) {
     73 	SplayNode *p = root;
     74 	while (1) {
     75 		int d = (w > p->weight);
     76 		if (!p->son[d])
     77 			return p->son[d] = new SplayNode(p, w);
     78 		p = p->son[d];
     79 	}
     80 }
     81 
     82 SplayNode *findPredecessor(SplayNode *rt) {
     83 	Splay(rt);
     84 	if (!rt->son[0]) return NULL;
     85 	SplayNode *p = rt->son[0];
     86 	while (p->son[1]) p = p->son[1];
     87 	return p;
     88 }
     89 
     90 SplayNode *findSuccessor(SplayNode *rt) {
     91 	Splay(rt);
     92 	if (!rt->son[1]) return NULL;
     93 	SplayNode *p = rt->son[1];
     94 	while (p->son[0]) p = p->son[0];
     95 	return p;
     96 }
    AC代码

  • 相关阅读:
    Gym102028L
    CF985G
    三元环 & 四元环计数 学习笔记
    Hall 定理 学习笔记
    CF36E
    CF1110G
    P6071
    可持久化数据结构 学习笔记
    多项式全家桶
    c++ 编译zlib
  • 原文地址:https://www.cnblogs.com/Rhein-E/p/9754669.html
Copyright © 2011-2022 走看看