[Codevs][1296][营业额统计]

原题地址


模板题,就不说了,相信做了前面几道题就会这个了。。。就找一找前驱和后继嘛。。。。

注意一个点:这里一个数的“前驱”和“后继”应包括那个数本身。[因为数据中有重复的数,我用bitset判重会re,不知是不是因为毒瘤数据。。。]

强上代码 :


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<cstdlib>
#include<cmath>
#include<cctype>

#include<bitset>

#define R121() ((rand() << 12) + (rand() << 7) + rand())
#define R233() (R121() % 45411445 + R121() % 4545128 + R121 () % 465187 + 1)

int ans; 


const int N = 4e4 + 7,INF = 0x7fffffff;


class Treap {
	private :
		struct Node {
			Node *son[2];
			int size,num,data,hr;
			Node () {}
			Node (int data,Node *fl) : data(data) { son[0] = son[1] = fl; hr = R233(); size = num = 1; }	
			void update () { size = son[0] -> size + son[1] -> size + num; }
		}*root,*pool,meme[N],*Null;
		
		int ball;
		
		void rotate (Node *&T,bool v) {
			Node *Tt = T -> son[v];
			T -> son[v] = Tt -> son[v^1];
			Tt -> son[v^1] = T;
			T -> update (); Tt -> update();
			T = Tt;		
		}
		
		void Insert (Node *&T) {
			if(T == Null) { T = new (pool++) Node(ball,Null);  return ;  }
			if(T -> data == ball) { ++ T -> size; ++ T -> num; return; }
			bool v = T -> data < ball;
			Insert (T -> son[v]);
			if(T -> son[v] -> hr < T -> hr) rotate (T , v);
			else T -> update(); 
		}
		
		int Subsequent (Node *&T) {
			if(T == Null) return -INF;
			if(T -> data < ball) return Subsequent (T -> son[1]);
			int k = Subsequent (T -> son[0]);
			return k == -INF ? T -> data : k;
		}
		
		int Precursor (Node *&T) {
//			printf("ds
");
			if(T == Null) { 
//			printf("sfd %d
",T -> data);
			return -INF;}
//			printf("dfas %d %d %d
",T -> data,ball,T -> son[0] -> data);
			if(T -> data > ball) return Precursor (T -> son[0]);
//			printf("dsl
");
			int k = Precursor (T -> son[1]);
			return k == -INF ? T -> data : k;
		}
		
	public :
		Treap () { Null = new Node (); Null -> size = Null -> num = 0; }
		void clear () { pool = meme; root = Null; }
		void Ins (int xxx) { ball = xxx; Insert (root); }
		int Sub (int xxx) { ball = xxx; return Subsequent (root); }
		int Pre (int xxx) { ball = xxx; return Precursor (root); }
		void Clc (int xxx) {
			if(!root -> size) ans += xxx; else {
				int a = Pre (xxx) , b = Sub (xxx);
//				printf("f %d %d %d %d %d %d %d
",xxx,r	oot->size,root->data ,root->son[0]->data,a,b,root == Null);
				if(a == -INF && b == -INF) return; //  
				else if(b == -INF) ans += xxx - a;
				else if(a == -INF) ans += b - xxx;
				else ans += std :: min (xxx - a,b - xxx); 
			}
			Ins (xxx);
		}
}treap;


int n,w;

int main () {
	scanf("%d",&n); treap . clear();
	for(int i=1;i<=n;++i) {
		scanf("%d",&w); treap.Clc(w);
	}
	printf("%d
",ans);
	return 0;
}

That is all. Thank you for watching.

原文地址:https://www.cnblogs.com/dcoi-king/p/5353659.html